//===-- 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 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 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 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 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 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 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 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 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 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 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 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 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 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()); }