diff options
Diffstat (limited to 'unittests/ADT/IntervalMapTest.cpp')
-rw-r--r-- | unittests/ADT/IntervalMapTest.cpp | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/unittests/ADT/IntervalMapTest.cpp b/unittests/ADT/IntervalMapTest.cpp new file mode 100644 index 0000000..b5556d2 --- /dev/null +++ b/unittests/ADT/IntervalMapTest.cpp @@ -0,0 +1,716 @@ +//===---- ADT/IntervalMapTest.cpp - IntervalMap unit tests ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/IntervalMap.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +typedef IntervalMap<unsigned, unsigned, 4> UUMap; + +// Empty map tests +TEST(IntervalMapTest, EmptyMap) { + UUMap::Allocator allocator; + UUMap map(allocator); + EXPECT_TRUE(map.empty()); + + // Lookup on empty map. + 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)); + + // Iterators. + 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()); + + // Default constructor and cross-constness compares. + UUMap::const_iterator CI; + CI = map.begin(); + EXPECT_TRUE(CI == I); + UUMap::iterator I2; + I2 = map.end(); + EXPECT_TRUE(I2 == CI); +} + +// Single entry map tests +TEST(IntervalMapTest, SingleEntryMap) { + UUMap::Allocator allocator; + UUMap map(allocator); + map.insert(100, 150, 1); + EXPECT_FALSE(map.empty()); + + // Lookup around interval. + 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)); + + // Iterators. + 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()); + + // Iter deref. + UUMap::iterator I = map.begin(); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(100u, I.start()); + EXPECT_EQ(150u, I.stop()); + EXPECT_EQ(1u, I.value()); + + // Preincrement. + ++I; + EXPECT_FALSE(I.valid()); + EXPECT_FALSE(I == map.begin()); + EXPECT_TRUE(I == map.end()); + + // PreDecrement. + --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()); + + // Change the value. + I.setValue(2); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(100u, I.start()); + EXPECT_EQ(150u, I.stop()); + EXPECT_EQ(2u, I.value()); + + // Grow the bounds. + 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()); + + // Shrink the bounds. + I.setStart(150); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(150u, I.start()); + EXPECT_EQ(200u, 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()); + + // Erase last elem. + I.erase(); + EXPECT_TRUE(map.empty()); + EXPECT_EQ(0, std::distance(map.begin(), map.end())); +} + +// Flat coalescing tests. +TEST(IntervalMapTest, RootCoalescing) { + UUMap::Allocator allocator; + UUMap map(allocator); + map.insert(100, 150, 1); + + // Coalesce from the left. + map.insert(90, 99, 1); + EXPECT_EQ(1, std::distance(map.begin(), map.end())); + EXPECT_EQ(90u, map.start()); + EXPECT_EQ(150u, map.stop()); + + // Coalesce from the right. + map.insert(151, 200, 1); + EXPECT_EQ(1, std::distance(map.begin(), map.end())); + EXPECT_EQ(90u, map.start()); + EXPECT_EQ(200u, map.stop()); + + // Non-coalesce from the left. + 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()); + + // Non-coalesce from the right. + 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)); + + // Erase from the left. + map.begin().erase(); + EXPECT_EQ(2, std::distance(map.begin(), map.end())); + EXPECT_EQ(90u, map.start()); + EXPECT_EQ(210u, map.stop()); + + // Erase from the right. + (--map.end()).erase(); + EXPECT_EQ(1, std::distance(map.begin(), map.end())); + EXPECT_EQ(90u, map.start()); + EXPECT_EQ(200u, map.stop()); + + // Add non-coalescing, then trigger coalescing with setValue. + 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()); +} + +// Flat multi-coalescing tests. +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()); + + // Verify inserts. + 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()); + + // Test advanceTo on flat tree. + 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()); + + // Coalesce left with followers. + // [100;110] [120;130] [140;150] [160;170] + 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()); + + // Coalesce right with followers. + // [100;115] [120;130] [140;150] [160;170] + 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()); + + // Coalesce left and right with followers. + // [100;115] [120;130] [135;150] [160;170] + 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()); + + // Test clear() on non-branched map. + map.clear(); + EXPECT_TRUE(map.empty()); + EXPECT_TRUE(map.begin() == map.end()); +} + +// Branched, non-coalescing tests. +TEST(IntervalMapTest, Branched) { + UUMap::Allocator allocator; + UUMap map(allocator); + + // Insert enough intervals to force a branched tree. + // This creates 9 leaf nodes with 11 elements each, tree height = 1. + 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()); + } + + // Tree limits. + EXPECT_FALSE(map.empty()); + EXPECT_EQ(10u, map.start()); + EXPECT_EQ(995u, map.stop()); + + // Tree lookup. + 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)); + } + + // Forward iteration. + 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()); + + // Backwards iteration. + 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()); + + // Test advanceTo in same node. + I.advanceTo(20); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(20u, I.start()); + EXPECT_EQ(25u, I.stop()); + + // Change value, no coalescing. + I.setValue(0); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(20u, I.start()); + EXPECT_EQ(25u, I.stop()); + EXPECT_EQ(0u, I.value()); + + // Close the gap right, no coalescing. + I.setStop(29); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(20u, I.start()); + EXPECT_EQ(29u, I.stop()); + EXPECT_EQ(0u, I.value()); + + // Change value, no coalescing. + I.setValue(2); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(20u, I.start()); + EXPECT_EQ(29u, I.stop()); + EXPECT_EQ(2u, I.value()); + + // Change value, now coalescing. + I.setValue(3); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(20u, I.start()); + EXPECT_EQ(35u, I.stop()); + EXPECT_EQ(3u, I.value()); + + // Close the gap, now coalescing. + 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()); + + // advanceTo another node. + I.advanceTo(200); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(200u, I.start()); + EXPECT_EQ(205u, I.stop()); + + // Close the gap left, no coalescing. + I.setStart(196); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(196u, I.start()); + EXPECT_EQ(205u, I.stop()); + EXPECT_EQ(20u, I.value()); + + // Change value, no coalescing. + I.setValue(0); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(196u, I.start()); + EXPECT_EQ(205u, I.stop()); + EXPECT_EQ(0u, I.value()); + + // Change value, now coalescing. + I.setValue(19); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(190u, I.start()); + EXPECT_EQ(205u, I.stop()); + EXPECT_EQ(19u, I.value()); + + // Close the gap, now coalescing. + 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()); + + // Erase from the front. + 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()); + } + + // Test clear() on branched map. + map.clear(); + EXPECT_TRUE(map.empty()); + EXPECT_TRUE(map.begin() == map.end()); +} + +// Branched, high, non-coalescing tests. +TEST(IntervalMapTest, Branched2) { + UUMap::Allocator allocator; + UUMap map(allocator); + + // Insert enough intervals to force a height >= 2 tree. + for (unsigned i = 1; i < 1000; ++i) + map.insert(10*i, 10*i+5, i); + + // Tree limits. + EXPECT_FALSE(map.empty()); + EXPECT_EQ(10u, map.start()); + EXPECT_EQ(9995u, map.stop()); + + // Tree lookup. + 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)); + } + + // Forward iteration. + 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()); + + // Backwards iteration. + 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()); + + // Test advanceTo in same node. + I.advanceTo(20); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(20u, I.start()); + EXPECT_EQ(25u, I.stop()); + + // advanceTo sibling leaf node. + I.advanceTo(200); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(200u, I.start()); + EXPECT_EQ(205u, I.stop()); + + // advanceTo further. + I.advanceTo(2000); + ASSERT_TRUE(I.valid()); + EXPECT_EQ(2000u, I.start()); + EXPECT_EQ(2005u, I.stop()); + + // advanceTo beyond end() + I.advanceTo(20000); + EXPECT_FALSE(I.valid()); + + // end().advanceTo() is valid as long as x > map.stop() + I.advanceTo(30000); + EXPECT_FALSE(I.valid()); + + // Test clear() on branched map. + map.clear(); + EXPECT_TRUE(map.empty()); + EXPECT_TRUE(map.begin() == map.end()); +} + +// Random insertions, coalescing to a single interval. +TEST(IntervalMapTest, RandomCoalescing) { + UUMap::Allocator allocator; + UUMap map(allocator); + + // This is a poor PRNG with maximal period: + // x_n = 5 x_{n-1} + 1 mod 2^N + + 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; + } + + // Map should be fully coalesced after that exercise. + EXPECT_FALSE(map.empty()); + EXPECT_EQ(0u, map.start()); + EXPECT_EQ(40959u, map.stop()); + EXPECT_EQ(1, std::distance(map.begin(), map.end())); + +} + +TEST(IntervalMapOverlapsTest, SmallMaps) { + typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps; + UUMap::Allocator allocator; + UUMap mapA(allocator); + UUMap mapB(allocator); + + // empty, empty. + EXPECT_FALSE(UUOverlaps(mapA, mapB).valid()); + + mapA.insert(1, 2, 3); + + // full, empty + EXPECT_FALSE(UUOverlaps(mapA, mapB).valid()); + // empty, full + EXPECT_FALSE(UUOverlaps(mapB, mapA).valid()); + + mapB.insert(3, 4, 5); + + // full, full, non-overlapping + EXPECT_FALSE(UUOverlaps(mapA, mapB).valid()); + EXPECT_FALSE(UUOverlaps(mapB, mapA).valid()); + + // Add an overlapping segment. + 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()); + // advance past end. + BA.advanceTo(6); + EXPECT_FALSE(BA.valid()); + // advance an invalid iterator. + BA.advanceTo(7); + EXPECT_FALSE(BA.valid()); +} + +TEST(IntervalMapOverlapsTest, BigMaps) { + typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps; + UUMap::Allocator allocator; + UUMap mapA(allocator); + UUMap mapB(allocator); + + // [0;4] [10;14] [20;24] ... + for (unsigned n = 0; n != 100; ++n) + mapA.insert(10*n, 10*n+4, n); + + // [5;6] [15;16] [25;26] ... + for (unsigned n = 10; n != 20; ++n) + mapB.insert(10*n+5, 10*n+6, n); + + // [208;209] [218;219] ... + for (unsigned n = 20; n != 30; ++n) + mapB.insert(10*n+8, 10*n+9, n); + + // insert some overlapping segments. + 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()); + + // Test advanceTo. + UUOverlaps AB2(mapA, mapB); + AB2.advanceTo(410); + ASSERT_TRUE(AB2.valid()); + EXPECT_EQ(410u, AB2.a().start()); + EXPECT_EQ(402u, AB2.b().start()); + + // It is valid to advanceTo with any monotonic sequence. + AB2.advanceTo(411); + ASSERT_TRUE(AB2.valid()); + EXPECT_EQ(410u, AB2.a().start()); + EXPECT_EQ(402u, AB2.b().start()); + + // Check reversed maps. + 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()); + + // Test advanceTo. + 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()); +} + +} // namespace |