//===------ ADT/SparseSetTest.cpp - SparseSet 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/SparseSet.h" #include "gtest/gtest.h" using namespace llvm; namespace { typedef SparseSet<unsigned> USet; // Empty set tests. TEST(SparseSetTest, EmptySet) { USet Set; EXPECT_TRUE(Set.empty()); EXPECT_TRUE(Set.begin() == Set.end()); EXPECT_EQ(0u, Set.size()); Set.setUniverse(10); // Lookups on empty set. EXPECT_TRUE(Set.find(0) == Set.end()); EXPECT_TRUE(Set.find(9) == Set.end()); // Same thing on a const reference. const USet &CSet = Set; EXPECT_TRUE(CSet.empty()); EXPECT_TRUE(CSet.begin() == CSet.end()); EXPECT_EQ(0u, CSet.size()); EXPECT_TRUE(CSet.find(0) == CSet.end()); USet::const_iterator I = CSet.find(5); EXPECT_TRUE(I == CSet.end()); } // Single entry set tests. TEST(SparseSetTest, SingleEntrySet) { USet Set; Set.setUniverse(10); std::pair<USet::iterator, bool> IP = Set.insert(5); EXPECT_TRUE(IP.second); EXPECT_TRUE(IP.first == Set.begin()); EXPECT_FALSE(Set.empty()); EXPECT_FALSE(Set.begin() == Set.end()); EXPECT_TRUE(Set.begin() + 1 == Set.end()); EXPECT_EQ(1u, Set.size()); EXPECT_TRUE(Set.find(0) == Set.end()); EXPECT_TRUE(Set.find(9) == Set.end()); EXPECT_FALSE(Set.count(0)); EXPECT_TRUE(Set.count(5)); // Redundant insert. IP = Set.insert(5); EXPECT_FALSE(IP.second); EXPECT_TRUE(IP.first == Set.begin()); // Erase non-existent element. EXPECT_FALSE(Set.erase(1)); EXPECT_EQ(1u, Set.size()); EXPECT_EQ(5u, *Set.begin()); // Erase iterator. USet::iterator I = Set.find(5); EXPECT_TRUE(I == Set.begin()); I = Set.erase(I); EXPECT_TRUE(I == Set.end()); EXPECT_TRUE(Set.empty()); } // Multiple entry set tests. TEST(SparseSetTest, MultipleEntrySet) { USet Set; Set.setUniverse(10); Set.insert(5); Set.insert(3); Set.insert(2); Set.insert(1); Set.insert(4); EXPECT_EQ(5u, Set.size()); // Without deletions, iteration order == insertion order. USet::const_iterator I = Set.begin(); EXPECT_EQ(5u, *I); ++I; EXPECT_EQ(3u, *I); ++I; EXPECT_EQ(2u, *I); ++I; EXPECT_EQ(1u, *I); ++I; EXPECT_EQ(4u, *I); ++I; EXPECT_TRUE(I == Set.end()); // Redundant insert. std::pair<USet::iterator, bool> IP = Set.insert(3); EXPECT_FALSE(IP.second); EXPECT_TRUE(IP.first == Set.begin() + 1); // Erase last element by key. EXPECT_TRUE(Set.erase(4)); EXPECT_EQ(4u, Set.size()); EXPECT_FALSE(Set.count(4)); EXPECT_FALSE(Set.erase(4)); EXPECT_EQ(4u, Set.size()); EXPECT_FALSE(Set.count(4)); // Erase first element by key. EXPECT_TRUE(Set.count(5)); EXPECT_TRUE(Set.find(5) == Set.begin()); EXPECT_TRUE(Set.erase(5)); EXPECT_EQ(3u, Set.size()); EXPECT_FALSE(Set.count(5)); EXPECT_FALSE(Set.erase(5)); EXPECT_EQ(3u, Set.size()); EXPECT_FALSE(Set.count(5)); Set.insert(6); Set.insert(7); EXPECT_EQ(5u, Set.size()); // Erase last element by iterator. I = Set.erase(Set.end() - 1); EXPECT_TRUE(I == Set.end()); EXPECT_EQ(4u, Set.size()); // Erase second element by iterator. I = Set.erase(Set.begin() + 1); EXPECT_TRUE(I == Set.begin() + 1); // Clear and resize the universe. Set.clear(); EXPECT_FALSE(Set.count(5)); Set.setUniverse(1000); // Add more than 256 elements. for (unsigned i = 100; i != 800; ++i) Set.insert(i); for (unsigned i = 0; i != 10; ++i) Set.erase(i); for (unsigned i = 100; i != 800; ++i) EXPECT_TRUE(Set.count(i)); EXPECT_FALSE(Set.count(99)); EXPECT_FALSE(Set.count(800)); EXPECT_EQ(700u, Set.size()); } struct Alt { unsigned Value; explicit Alt(unsigned x) : Value(x) {} unsigned getSparseSetIndex() const { return Value - 1000; } }; TEST(SparseSetTest, AltStructSet) { typedef SparseSet<Alt> ASet; ASet Set; Set.setUniverse(10); Set.insert(Alt(1005)); ASet::iterator I = Set.find(5); ASSERT_TRUE(I == Set.begin()); EXPECT_EQ(1005u, I->Value); Set.insert(Alt(1006)); Set.insert(Alt(1006)); I = Set.erase(Set.begin()); ASSERT_TRUE(I == Set.begin()); EXPECT_EQ(1006u, I->Value); EXPECT_FALSE(Set.erase(5)); EXPECT_TRUE(Set.erase(6)); } TEST(SparseSetTest, PopBack) { USet Set; const unsigned UpperBound = 300; Set.setUniverse(UpperBound); for (unsigned i = 0; i < UpperBound; ++i) Set.insert(i); // Make sure pop back returns the values in the reverse order we // inserted them. unsigned Expected = UpperBound; while (!Set.empty()) ASSERT_TRUE(--Expected == Set.pop_back_val()); // Insert again the same elements in the sparse set and make sure // each insertion actually inserts the elements. I.e., check // that the underlying data structure are properly cleared. for (unsigned i = 0; i < UpperBound; ++i) ASSERT_TRUE(Set.insert(i).second); } } // namespace