In non-coalescing IntervalMaps the value type should not be requried to be equality-comparable.
205 lines
7.0 KiB
C++
205 lines
7.0 KiB
C++
//===-- interval_map_test.cpp ---------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of the ORC runtime.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "interval_map.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace __orc_rt;
|
|
|
|
TEST(IntervalMapTest, DefaultConstructed) {
|
|
// Check that a default-constructed IntervalMap behaves as expected.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
|
|
|
EXPECT_TRUE(M.empty());
|
|
EXPECT_TRUE(M.begin() == M.end());
|
|
EXPECT_TRUE(M.find(0) == M.end());
|
|
}
|
|
|
|
TEST(IntervalMapTest, InsertSingleElement) {
|
|
// Check that a map with a single element inserted behaves as expected.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
|
|
|
M.insert(7, 8, 42);
|
|
|
|
EXPECT_FALSE(M.empty());
|
|
EXPECT_EQ(std::next(M.begin()), M.end());
|
|
EXPECT_EQ(M.find(7), M.begin());
|
|
EXPECT_EQ(M.find(8), M.end());
|
|
EXPECT_EQ(M.lookup(7), 42U);
|
|
EXPECT_EQ(M.lookup(8), 0U); // 8 not present, so should return unsigned().
|
|
}
|
|
|
|
TEST(IntervalMapTest, InsertCoalesceWithPrevious) {
|
|
// Check that insertions coalesce with previous ranges that share the same
|
|
// value. Also check that they _don't_ coalesce if the values are different.
|
|
|
|
// Check that insertion coalesces with previous range when values are equal.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
|
|
|
|
M1.insert(7, 8, 42);
|
|
M1.insert(8, 9, 42);
|
|
|
|
EXPECT_FALSE(M1.empty());
|
|
EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
|
|
EXPECT_EQ(M1.find(7), M1.find(8)); // 7 and 8 should point to same range.
|
|
EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
|
|
|
|
// Check that insertion does not coalesce with previous range when values are
|
|
// not equal.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
|
|
|
|
M2.insert(7, 8, 42);
|
|
M2.insert(8, 9, 7);
|
|
|
|
EXPECT_FALSE(M2.empty());
|
|
EXPECT_EQ(std::next(std::next(M2.begin())), M2.end()); // Expect two ranges.
|
|
EXPECT_NE(M2.find(7), M2.find(8)); // 7 and 8 should be different ranges.
|
|
EXPECT_EQ(M2.lookup(7), 42U); // Keys 7 and 8 should map to different values.
|
|
EXPECT_EQ(M2.lookup(8), 7U);
|
|
}
|
|
|
|
TEST(IntervalMapTest, InsertCoalesceWithFollowing) {
|
|
// Check that insertions coalesce with following ranges that share the same
|
|
// value. Also check that they _don't_ coalesce if the values are different.
|
|
|
|
// Check that insertion coalesces with following range when values are equal.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
|
|
|
|
M1.insert(8, 9, 42);
|
|
M1.insert(7, 8, 42);
|
|
|
|
EXPECT_FALSE(M1.empty());
|
|
EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
|
|
EXPECT_EQ(M1.find(7), M1.find(8)); // 7 and 8 should point to same range.
|
|
EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
|
|
|
|
// Check that insertion does not coalesce with previous range when values are
|
|
// not equal.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
|
|
|
|
M2.insert(8, 9, 42);
|
|
M2.insert(7, 8, 7);
|
|
|
|
EXPECT_FALSE(M2.empty());
|
|
EXPECT_EQ(std::next(std::next(M2.begin())), M2.end()); // Expect two ranges.
|
|
EXPECT_EQ(M2.lookup(7), 7U); // Keys 7 and 8 should map to different values.
|
|
EXPECT_EQ(M2.lookup(8), 42U);
|
|
}
|
|
|
|
TEST(IntervalMapTest, InsertCoalesceBoth) {
|
|
// Check that insertions coalesce with ranges on both sides where posssible.
|
|
// Also check that they _don't_ coalesce if the values are different.
|
|
|
|
// Check that insertion coalesces with both previous and following ranges
|
|
// when values are equal.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
|
|
|
|
M1.insert(7, 8, 42);
|
|
M1.insert(9, 10, 42);
|
|
|
|
// Check no coalescing yet.
|
|
EXPECT_NE(M1.find(7), M1.find(9));
|
|
|
|
// Insert a 3rd range to trigger coalescing on both sides.
|
|
M1.insert(8, 9, 42);
|
|
|
|
EXPECT_FALSE(M1.empty());
|
|
EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
|
|
EXPECT_EQ(M1.find(7), M1.find(8)); // 7, 8, and 9 should point to same range.
|
|
EXPECT_EQ(M1.find(8), M1.find(9));
|
|
EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
|
|
|
|
// Check that insertion does not coalesce with previous range when values are
|
|
// not equal.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
|
|
|
|
M2.insert(7, 8, 42);
|
|
M2.insert(8, 9, 7);
|
|
M2.insert(9, 10, 42);
|
|
|
|
EXPECT_FALSE(M2.empty());
|
|
// Expect three ranges.
|
|
EXPECT_EQ(std::next(std::next(std::next(M2.begin()))), M2.end());
|
|
EXPECT_NE(M2.find(7), M2.find(8)); // All keys should map to different ranges.
|
|
EXPECT_NE(M2.find(8), M2.find(9));
|
|
EXPECT_EQ(M2.lookup(7), 42U); // Key 7, 8, and 9 should map to different vals.
|
|
EXPECT_EQ(M2.lookup(8), 7U);
|
|
EXPECT_EQ(M2.lookup(9), 42U);
|
|
}
|
|
|
|
TEST(IntervalMapTest, EraseSingleElement) {
|
|
// Check that we can insert and then remove a single range.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
|
|
|
M.insert(7, 10, 42);
|
|
EXPECT_FALSE(M.empty());
|
|
M.erase(7, 10);
|
|
EXPECT_TRUE(M.empty());
|
|
}
|
|
|
|
TEST(IntervalMapTest, EraseSplittingLeft) {
|
|
// Check that removal of a trailing subrange succeeds, but leaves the
|
|
// residual range in-place.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
|
|
|
M.insert(7, 10, 42);
|
|
EXPECT_FALSE(M.empty());
|
|
M.erase(9, 10);
|
|
EXPECT_EQ(std::next(M.begin()), M.end());
|
|
EXPECT_EQ(M.begin()->first.first, 7U);
|
|
EXPECT_EQ(M.begin()->first.second, 9U);
|
|
}
|
|
|
|
TEST(IntervalMapTest, EraseSplittingRight) {
|
|
// Check that removal of a leading subrange succeeds, but leaves the
|
|
// residual range in-place.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
|
|
|
M.insert(7, 10, 42);
|
|
EXPECT_FALSE(M.empty());
|
|
M.erase(7, 8);
|
|
EXPECT_EQ(std::next(M.begin()), M.end());
|
|
EXPECT_EQ(M.begin()->first.first, 8U);
|
|
EXPECT_EQ(M.begin()->first.second, 10U);
|
|
}
|
|
|
|
TEST(IntervalMapTest, EraseSplittingBoth) {
|
|
// Check that removal of an interior subrange leaves both the leading and
|
|
// trailing residual subranges in-place.
|
|
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
|
|
|
M.insert(7, 10, 42);
|
|
EXPECT_FALSE(M.empty());
|
|
M.erase(8, 9);
|
|
EXPECT_EQ(std::next(std::next(M.begin())), M.end());
|
|
EXPECT_EQ(M.begin()->first.first, 7U);
|
|
EXPECT_EQ(M.begin()->first.second, 8U);
|
|
EXPECT_EQ(std::next(M.begin())->first.first, 9U);
|
|
EXPECT_EQ(std::next(M.begin())->first.second, 10U);
|
|
}
|
|
|
|
TEST(IntervalMapTest, NonCoalescingMapPermitsNonComparableKeys) {
|
|
// Test that values that can't be equality-compared are still usable when
|
|
// coalescing is disabled and behave as expected.
|
|
|
|
struct S {}; // Struct with no equality comparison.
|
|
|
|
IntervalMap<unsigned, S, IntervalCoalescing::Disabled> M;
|
|
|
|
M.insert(7, 8, S());
|
|
|
|
EXPECT_FALSE(M.empty());
|
|
EXPECT_EQ(std::next(M.begin()), M.end());
|
|
EXPECT_EQ(M.find(7), M.begin());
|
|
EXPECT_EQ(M.find(8), M.end());
|
|
}
|