|  | //===- llvm/unittest/ADT/BitVectorTest.cpp - BitVector tests --------------===// | 
|  | // | 
|  | // 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 | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/ADT/BitVector.h" | 
|  | #include "llvm/ADT/DenseSet.h" | 
|  | #include "llvm/ADT/SmallBitVector.h" | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // Test fixture | 
|  | template <typename T> | 
|  | class BitVectorTest : public ::testing::Test { }; | 
|  |  | 
|  | // Test both BitVector and SmallBitVector with the same suite of tests. | 
|  | typedef ::testing::Types<BitVector, SmallBitVector> BitVectorTestTypes; | 
|  | TYPED_TEST_SUITE(BitVectorTest, BitVectorTestTypes, ); | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, TrivialOperation) { | 
|  | TypeParam Vec; | 
|  | EXPECT_EQ(0U, Vec.count()); | 
|  | EXPECT_EQ(0U, Vec.size()); | 
|  | EXPECT_FALSE(Vec.any()); | 
|  | EXPECT_TRUE(Vec.all()); | 
|  | EXPECT_TRUE(Vec.none()); | 
|  | EXPECT_TRUE(Vec.empty()); | 
|  |  | 
|  | Vec.resize(5, true); | 
|  | EXPECT_EQ(5U, Vec.count()); | 
|  | EXPECT_EQ(5U, Vec.size()); | 
|  | EXPECT_TRUE(Vec.any()); | 
|  | EXPECT_TRUE(Vec.all()); | 
|  | EXPECT_FALSE(Vec.none()); | 
|  | EXPECT_FALSE(Vec.empty()); | 
|  |  | 
|  | Vec.resize(11); | 
|  | EXPECT_EQ(5U, Vec.count()); | 
|  | EXPECT_EQ(11U, Vec.size()); | 
|  | EXPECT_TRUE(Vec.any()); | 
|  | EXPECT_FALSE(Vec.all()); | 
|  | EXPECT_FALSE(Vec.none()); | 
|  | EXPECT_FALSE(Vec.empty()); | 
|  |  | 
|  | TypeParam Inv = Vec; | 
|  | Inv.flip(); | 
|  | EXPECT_EQ(6U, Inv.count()); | 
|  | EXPECT_EQ(11U, Inv.size()); | 
|  | EXPECT_TRUE(Inv.any()); | 
|  | EXPECT_FALSE(Inv.all()); | 
|  | EXPECT_FALSE(Inv.none()); | 
|  | EXPECT_FALSE(Inv.empty()); | 
|  |  | 
|  | EXPECT_FALSE(Inv == Vec); | 
|  | EXPECT_TRUE(Inv != Vec); | 
|  | Vec.flip(); | 
|  | EXPECT_TRUE(Inv == Vec); | 
|  | EXPECT_FALSE(Inv != Vec); | 
|  |  | 
|  | // Add some "interesting" data to Vec. | 
|  | Vec.resize(23, true); | 
|  | Vec.resize(25, false); | 
|  | Vec.resize(26, true); | 
|  | Vec.resize(29, false); | 
|  | Vec.resize(33, true); | 
|  | Vec.resize(57, false); | 
|  | unsigned Count = 0; | 
|  | for (unsigned i = Vec.find_first(); i != -1u; i = Vec.find_next(i)) { | 
|  | ++Count; | 
|  | EXPECT_TRUE(Vec[i]); | 
|  | EXPECT_TRUE(Vec.test(i)); | 
|  | } | 
|  | EXPECT_EQ(Count, Vec.count()); | 
|  | EXPECT_EQ(Count, 23u); | 
|  | EXPECT_FALSE(Vec[0]); | 
|  | EXPECT_TRUE(Vec[32]); | 
|  | EXPECT_FALSE(Vec[56]); | 
|  | Vec.resize(61, false); | 
|  |  | 
|  | TypeParam Copy = Vec; | 
|  | TypeParam Alt(3, false); | 
|  | Alt.resize(6, true); | 
|  | std::swap(Alt, Vec); | 
|  | EXPECT_TRUE(Copy == Alt); | 
|  | EXPECT_TRUE(Vec.size() == 6); | 
|  | EXPECT_TRUE(Vec.count() == 3); | 
|  | EXPECT_TRUE(Vec.find_first() == 3); | 
|  | std::swap(Copy, Vec); | 
|  |  | 
|  | // Add some more "interesting" data. | 
|  | Vec.resize(68, true); | 
|  | Vec.resize(78, false); | 
|  | Vec.resize(89, true); | 
|  | Vec.resize(90, false); | 
|  | Vec.resize(91, true); | 
|  | Vec.resize(130, false); | 
|  | Count = 0; | 
|  | for (unsigned i = Vec.find_first(); i != -1u; i = Vec.find_next(i)) { | 
|  | ++Count; | 
|  | EXPECT_TRUE(Vec[i]); | 
|  | EXPECT_TRUE(Vec.test(i)); | 
|  | } | 
|  | EXPECT_EQ(Count, Vec.count()); | 
|  | EXPECT_EQ(Count, 42u); | 
|  | EXPECT_FALSE(Vec[0]); | 
|  | EXPECT_TRUE(Vec[32]); | 
|  | EXPECT_FALSE(Vec[60]); | 
|  | EXPECT_FALSE(Vec[129]); | 
|  |  | 
|  | Vec.flip(60); | 
|  | EXPECT_TRUE(Vec[60]); | 
|  | EXPECT_EQ(Count + 1, Vec.count()); | 
|  | Vec.flip(60); | 
|  | EXPECT_FALSE(Vec[60]); | 
|  | EXPECT_EQ(Count, Vec.count()); | 
|  |  | 
|  | Vec.reset(32); | 
|  | EXPECT_FALSE(Vec[32]); | 
|  | EXPECT_EQ(Count - 1, Vec.count()); | 
|  | Vec.set(32); | 
|  | EXPECT_TRUE(Vec[32]); | 
|  | EXPECT_EQ(Count, Vec.count()); | 
|  |  | 
|  | Vec.flip(); | 
|  | EXPECT_EQ(Vec.size() - Count, Vec.count()); | 
|  |  | 
|  | Vec.reset(); | 
|  | EXPECT_EQ(0U, Vec.count()); | 
|  | EXPECT_EQ(130U, Vec.size()); | 
|  | EXPECT_FALSE(Vec.any()); | 
|  | EXPECT_FALSE(Vec.all()); | 
|  | EXPECT_TRUE(Vec.none()); | 
|  | EXPECT_FALSE(Vec.empty()); | 
|  |  | 
|  | Vec.flip(); | 
|  | EXPECT_EQ(130U, Vec.count()); | 
|  | EXPECT_EQ(130U, Vec.size()); | 
|  | EXPECT_TRUE(Vec.any()); | 
|  | EXPECT_TRUE(Vec.all()); | 
|  | EXPECT_FALSE(Vec.none()); | 
|  | EXPECT_FALSE(Vec.empty()); | 
|  |  | 
|  | Vec.resize(64); | 
|  | EXPECT_EQ(64U, Vec.count()); | 
|  | EXPECT_EQ(64U, Vec.size()); | 
|  | EXPECT_TRUE(Vec.any()); | 
|  | EXPECT_TRUE(Vec.all()); | 
|  | EXPECT_FALSE(Vec.none()); | 
|  | EXPECT_FALSE(Vec.empty()); | 
|  |  | 
|  | Vec.flip(); | 
|  | EXPECT_EQ(0U, Vec.count()); | 
|  | EXPECT_EQ(64U, Vec.size()); | 
|  | EXPECT_FALSE(Vec.any()); | 
|  | EXPECT_FALSE(Vec.all()); | 
|  | EXPECT_TRUE(Vec.none()); | 
|  | EXPECT_FALSE(Vec.empty()); | 
|  |  | 
|  | Inv = TypeParam().flip(); | 
|  | EXPECT_EQ(0U, Inv.count()); | 
|  | EXPECT_EQ(0U, Inv.size()); | 
|  | EXPECT_FALSE(Inv.any()); | 
|  | EXPECT_TRUE(Inv.all()); | 
|  | EXPECT_TRUE(Inv.none()); | 
|  | EXPECT_TRUE(Inv.empty()); | 
|  |  | 
|  | Vec.clear(); | 
|  | EXPECT_EQ(0U, Vec.count()); | 
|  | EXPECT_EQ(0U, Vec.size()); | 
|  | EXPECT_FALSE(Vec.any()); | 
|  | EXPECT_TRUE(Vec.all()); | 
|  | EXPECT_TRUE(Vec.none()); | 
|  | EXPECT_TRUE(Vec.empty()); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, Equality) { | 
|  | TypeParam A; | 
|  | TypeParam B; | 
|  | EXPECT_TRUE(A == B); | 
|  | A.resize(10); | 
|  | EXPECT_FALSE(A == B); | 
|  | B.resize(10); | 
|  | EXPECT_TRUE(A == B); | 
|  | A.set(5); | 
|  | EXPECT_FALSE(A == B); | 
|  | B.set(5); | 
|  | EXPECT_TRUE(A == B); | 
|  | A.resize(20); | 
|  | EXPECT_FALSE(A == B); | 
|  | B.resize(20); | 
|  | EXPECT_TRUE(A == B); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, SimpleFindOpsMultiWord) { | 
|  | TypeParam A; | 
|  |  | 
|  | // Test finding next set and unset bits in a BitVector with multiple words | 
|  | A.resize(100); | 
|  | A.set(12); | 
|  | A.set(13); | 
|  | A.set(75); | 
|  |  | 
|  | EXPECT_EQ(75, A.find_last()); | 
|  | EXPECT_EQ(12, A.find_first()); | 
|  | EXPECT_EQ(13, A.find_next(12)); | 
|  | EXPECT_EQ(75, A.find_next(13)); | 
|  | EXPECT_EQ(-1, A.find_next(75)); | 
|  |  | 
|  | EXPECT_EQ(-1, A.find_prev(12)); | 
|  | EXPECT_EQ(12, A.find_prev(13)); | 
|  | EXPECT_EQ(13, A.find_prev(75)); | 
|  | EXPECT_EQ(75, A.find_prev(90)); | 
|  |  | 
|  | EXPECT_EQ(0, A.find_first_unset()); | 
|  | EXPECT_EQ(99, A.find_last_unset()); | 
|  | EXPECT_EQ(14, A.find_next_unset(11)); | 
|  | EXPECT_EQ(14, A.find_next_unset(12)); | 
|  | EXPECT_EQ(14, A.find_next_unset(13)); | 
|  | EXPECT_EQ(16, A.find_next_unset(15)); | 
|  | EXPECT_EQ(76, A.find_next_unset(74)); | 
|  | EXPECT_EQ(76, A.find_next_unset(75)); | 
|  | EXPECT_EQ(-1, A.find_next_unset(99)); | 
|  |  | 
|  | A.set(0, 100); | 
|  | EXPECT_EQ(100U, A.count()); | 
|  | EXPECT_EQ(0, A.find_first()); | 
|  | EXPECT_EQ(-1, A.find_first_unset()); | 
|  | EXPECT_EQ(-1, A.find_last_unset()); | 
|  | EXPECT_EQ(99, A.find_last()); | 
|  | EXPECT_EQ(99, A.find_next(98)); | 
|  |  | 
|  | A.reset(0, 100); | 
|  | EXPECT_EQ(0U, A.count()); | 
|  | EXPECT_EQ(-1, A.find_first()); | 
|  | EXPECT_EQ(-1, A.find_last()); | 
|  | EXPECT_EQ(0, A.find_first_unset()); | 
|  | EXPECT_EQ(99, A.find_last_unset()); | 
|  | EXPECT_EQ(99, A.find_next_unset(98)); | 
|  | } | 
|  |  | 
|  | // Test finding next set and unset bits in a BitVector/SmallBitVector within a | 
|  | // uintptr_t - check both 32-bit (Multi) and 64-bit (Small) targets. | 
|  | TYPED_TEST(BitVectorTest, SimpleFindOps64Bit) { | 
|  | TypeParam A; | 
|  |  | 
|  | A.resize(57); | 
|  | A.set(12); | 
|  | A.set(13); | 
|  | A.set(47); | 
|  |  | 
|  | EXPECT_EQ(47, A.find_last()); | 
|  | EXPECT_EQ(12, A.find_first()); | 
|  | EXPECT_EQ(13, A.find_next(12)); | 
|  | EXPECT_EQ(47, A.find_next(13)); | 
|  | EXPECT_EQ(-1, A.find_next(47)); | 
|  |  | 
|  | EXPECT_EQ(-1, A.find_prev(12)); | 
|  | EXPECT_EQ(12, A.find_prev(13)); | 
|  | EXPECT_EQ(13, A.find_prev(47)); | 
|  | EXPECT_EQ(47, A.find_prev(56)); | 
|  |  | 
|  | EXPECT_EQ(0, A.find_first_unset()); | 
|  | EXPECT_EQ(56, A.find_last_unset()); | 
|  | EXPECT_EQ(14, A.find_next_unset(11)); | 
|  | EXPECT_EQ(14, A.find_next_unset(12)); | 
|  | EXPECT_EQ(14, A.find_next_unset(13)); | 
|  | EXPECT_EQ(16, A.find_next_unset(15)); | 
|  | EXPECT_EQ(48, A.find_next_unset(46)); | 
|  | EXPECT_EQ(48, A.find_next_unset(47)); | 
|  | EXPECT_EQ(-1, A.find_next_unset(56)); | 
|  | } | 
|  |  | 
|  | // Check if a SmallBitVector is in small mode. This check is used in tests | 
|  | // that run for both SmallBitVector and BitVector. This check doesn't apply | 
|  | // to BitVector so we provide an overload that returns true to get the tests | 
|  | // to compile. | 
|  | static bool SmallBitVectorIsSmallMode(const SmallBitVector &bv) { | 
|  | return bv.isSmall(); | 
|  | } | 
|  | static bool SmallBitVectorIsSmallMode(const BitVector &) { return true; } | 
|  |  | 
|  | // These tests are intended to exercise the single-word case of BitVector | 
|  | // and the small-mode case of SmallBitVector. | 
|  | TYPED_TEST(BitVectorTest, SimpleFindOpsSingleWord) { | 
|  | // Test finding in an empty BitVector. | 
|  | TypeParam A; | 
|  | ASSERT_TRUE(SmallBitVectorIsSmallMode(A)); | 
|  | EXPECT_EQ(-1, A.find_first()); | 
|  | EXPECT_EQ(-1, A.find_last()); | 
|  | EXPECT_EQ(-1, A.find_first_unset()); | 
|  | EXPECT_EQ(-1, A.find_last_unset()); | 
|  |  | 
|  | A.resize(20); | 
|  | ASSERT_TRUE(SmallBitVectorIsSmallMode(A)); | 
|  | EXPECT_EQ(-1, A.find_first()); | 
|  | EXPECT_EQ(-1, A.find_last()); | 
|  | EXPECT_EQ(-1, A.find_next(5)); | 
|  | EXPECT_EQ(-1, A.find_next(19)); | 
|  | EXPECT_EQ(-1, A.find_prev(5)); | 
|  | EXPECT_EQ(-1, A.find_prev(20)); | 
|  | EXPECT_EQ(0, A.find_first_unset()); | 
|  | EXPECT_EQ(19, A.find_last_unset()); | 
|  | EXPECT_EQ(6, A.find_next_unset(5)); | 
|  | EXPECT_EQ(-1, A.find_next_unset(19)); | 
|  |  | 
|  | A.set(3); | 
|  | A.set(4); | 
|  | A.set(16); | 
|  | ASSERT_TRUE(SmallBitVectorIsSmallMode(A)); | 
|  | EXPECT_EQ(16, A.find_last()); | 
|  | EXPECT_EQ(3, A.find_first()); | 
|  | EXPECT_EQ(3, A.find_next(1)); | 
|  | EXPECT_EQ(4, A.find_next(3)); | 
|  | EXPECT_EQ(16, A.find_next(4)); | 
|  | EXPECT_EQ(-1, A.find_next(16)); | 
|  |  | 
|  | EXPECT_EQ(-1, A.find_prev(3)); | 
|  | EXPECT_EQ(3, A.find_prev(4)); | 
|  | EXPECT_EQ(4, A.find_prev(16)); | 
|  | EXPECT_EQ(16, A.find_prev(18)); | 
|  |  | 
|  | EXPECT_EQ(0, A.find_first_unset()); | 
|  | EXPECT_EQ(19, A.find_last_unset()); | 
|  | EXPECT_EQ(5, A.find_next_unset(3)); | 
|  | EXPECT_EQ(5, A.find_next_unset(4)); | 
|  | EXPECT_EQ(13, A.find_next_unset(12)); | 
|  | EXPECT_EQ(17, A.find_next_unset(15)); | 
|  |  | 
|  | A.set(); | 
|  | ASSERT_TRUE(SmallBitVectorIsSmallMode(A)); | 
|  | EXPECT_EQ(0, A.find_first()); | 
|  | EXPECT_EQ(19, A.find_last()); | 
|  | EXPECT_EQ(6, A.find_next(5)); | 
|  | EXPECT_EQ(-1, A.find_next(19)); | 
|  | EXPECT_EQ(4, A.find_prev(5)); | 
|  | EXPECT_EQ(19, A.find_prev(20)); | 
|  | EXPECT_EQ(-1, A.find_first_unset()); | 
|  | EXPECT_EQ(-1, A.find_last_unset()); | 
|  | EXPECT_EQ(-1, A.find_next_unset(5)); | 
|  | EXPECT_EQ(-1, A.find_next_unset(19)); | 
|  | } | 
|  |  | 
|  | TEST(BitVectorTest, FindInRangeMultiWord) { | 
|  | BitVector Vec; | 
|  |  | 
|  | Vec.resize(200); | 
|  | Vec.set(3, 7); | 
|  | Vec.set(24, 35); | 
|  | Vec.set(50, 70); | 
|  | Vec.set(150); | 
|  | Vec.set(152); | 
|  | Vec.set(154); | 
|  |  | 
|  | // find first | 
|  | EXPECT_EQ(-1, Vec.find_first_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_first_in(24, 24)); | 
|  | EXPECT_EQ(-1, Vec.find_first_in(7, 24)); | 
|  |  | 
|  | EXPECT_EQ(3, Vec.find_first_in(0, 10)); | 
|  | EXPECT_EQ(4, Vec.find_first_in(4, 10)); | 
|  | EXPECT_EQ(150, Vec.find_first_in(100, 200)); | 
|  | EXPECT_EQ(152, Vec.find_first_in(151, 200)); | 
|  | EXPECT_EQ(154, Vec.find_first_in(153, 200)); | 
|  |  | 
|  | EXPECT_EQ(-1, Vec.find_first_in(155, 200)); | 
|  | Vec.set(199); | 
|  | EXPECT_EQ(199, Vec.find_first_in(199, 200)); | 
|  | Vec.reset(199); | 
|  |  | 
|  | // find last | 
|  | EXPECT_EQ(-1, Vec.find_last_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_last_in(24, 24)); | 
|  | EXPECT_EQ(-1, Vec.find_last_in(7, 24)); | 
|  |  | 
|  | EXPECT_EQ(6, Vec.find_last_in(0, 10)); | 
|  | EXPECT_EQ(5, Vec.find_last_in(0, 6)); | 
|  | EXPECT_EQ(154, Vec.find_last_in(100, 155)); | 
|  | EXPECT_EQ(152, Vec.find_last_in(100, 154)); | 
|  | EXPECT_EQ(150, Vec.find_last_in(100, 152)); | 
|  | EXPECT_EQ(-1, Vec.find_last_in(100, 150)); | 
|  | Vec.set(199); | 
|  | EXPECT_EQ(199, Vec.find_last_in(199, 200)); | 
|  | Vec.reset(199); | 
|  |  | 
|  | // find first unset | 
|  | EXPECT_EQ(-1, Vec.find_first_unset_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_first_unset_in(23, 23)); | 
|  | EXPECT_EQ(-1, Vec.find_first_unset_in(24, 35)); | 
|  |  | 
|  | EXPECT_EQ(0, Vec.find_first_unset_in(0, 10)); | 
|  | EXPECT_EQ(1, Vec.find_first_unset_in(1, 10)); | 
|  | EXPECT_EQ(7, Vec.find_first_unset_in(5, 25)); | 
|  | EXPECT_EQ(151, Vec.find_first_unset_in(150, 200)); | 
|  | EXPECT_EQ(151, Vec.find_first_unset_in(151, 200)); | 
|  | EXPECT_EQ(153, Vec.find_first_unset_in(152, 200)); | 
|  | EXPECT_EQ(153, Vec.find_first_unset_in(153, 200)); | 
|  | EXPECT_EQ(155, Vec.find_first_unset_in(154, 200)); | 
|  | EXPECT_EQ(155, Vec.find_first_unset_in(155, 200)); | 
|  | EXPECT_EQ(199, Vec.find_first_unset_in(199, 200)); | 
|  |  | 
|  | // find last unset | 
|  | EXPECT_EQ(-1, Vec.find_last_unset_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_last_unset_in(23, 23)); | 
|  | EXPECT_EQ(-1, Vec.find_last_unset_in(24, 35)); | 
|  |  | 
|  | EXPECT_EQ(9, Vec.find_last_unset_in(0, 10)); | 
|  | EXPECT_EQ(8, Vec.find_last_unset_in(0, 9)); | 
|  | EXPECT_EQ(2, Vec.find_last_unset_in(0, 7)); | 
|  | EXPECT_EQ(149, Vec.find_last_unset_in(100, 151)); | 
|  | EXPECT_EQ(151, Vec.find_last_unset_in(100, 152)); | 
|  | EXPECT_EQ(151, Vec.find_last_unset_in(100, 153)); | 
|  | EXPECT_EQ(153, Vec.find_last_unset_in(100, 154)); | 
|  | EXPECT_EQ(153, Vec.find_last_unset_in(100, 155)); | 
|  | EXPECT_EQ(155, Vec.find_last_unset_in(100, 156)); | 
|  | EXPECT_EQ(199, Vec.find_last_unset_in(199, 200)); | 
|  | } | 
|  |  | 
|  | TEST(BitVectorTest, FindInRangeSingleWord) { | 
|  | // When the bit vector contains only a single word, this is slightly different | 
|  | // than when the bit vector contains multiple words, because masks are applied | 
|  | // to the front and back of the same word.  So make sure this works. | 
|  | BitVector Vec; | 
|  |  | 
|  | Vec.resize(25); | 
|  | Vec.set(2, 4); | 
|  | Vec.set(6, 9); | 
|  | Vec.set(12, 15); | 
|  | Vec.set(19); | 
|  | Vec.set(21); | 
|  | Vec.set(23); | 
|  |  | 
|  | // find first | 
|  | EXPECT_EQ(-1, Vec.find_first_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_first_in(24, 24)); | 
|  | EXPECT_EQ(-1, Vec.find_first_in(9, 12)); | 
|  |  | 
|  | EXPECT_EQ(2, Vec.find_first_in(0, 10)); | 
|  | EXPECT_EQ(6, Vec.find_first_in(4, 10)); | 
|  | EXPECT_EQ(19, Vec.find_first_in(18, 25)); | 
|  | EXPECT_EQ(21, Vec.find_first_in(20, 25)); | 
|  | EXPECT_EQ(23, Vec.find_first_in(22, 25)); | 
|  | EXPECT_EQ(-1, Vec.find_first_in(24, 25)); | 
|  |  | 
|  | // find last | 
|  | EXPECT_EQ(-1, Vec.find_last_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_last_in(24, 24)); | 
|  | EXPECT_EQ(-1, Vec.find_last_in(9, 12)); | 
|  |  | 
|  | EXPECT_EQ(8, Vec.find_last_in(0, 10)); | 
|  | EXPECT_EQ(3, Vec.find_last_in(0, 6)); | 
|  | EXPECT_EQ(23, Vec.find_last_in(18, 25)); | 
|  | EXPECT_EQ(21, Vec.find_last_in(18, 23)); | 
|  | EXPECT_EQ(19, Vec.find_last_in(18, 21)); | 
|  | EXPECT_EQ(-1, Vec.find_last_in(18, 19)); | 
|  |  | 
|  | // find first unset | 
|  | EXPECT_EQ(-1, Vec.find_first_unset_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_first_unset_in(23, 23)); | 
|  | EXPECT_EQ(-1, Vec.find_first_unset_in(6, 9)); | 
|  |  | 
|  | EXPECT_EQ(0, Vec.find_first_unset_in(0, 6)); | 
|  | EXPECT_EQ(1, Vec.find_first_unset_in(1, 6)); | 
|  | EXPECT_EQ(9, Vec.find_first_unset_in(7, 13)); | 
|  | EXPECT_EQ(18, Vec.find_first_unset_in(18, 25)); | 
|  | EXPECT_EQ(20, Vec.find_first_unset_in(19, 25)); | 
|  | EXPECT_EQ(20, Vec.find_first_unset_in(20, 25)); | 
|  | EXPECT_EQ(22, Vec.find_first_unset_in(21, 25)); | 
|  | EXPECT_EQ(22, Vec.find_first_unset_in(22, 25)); | 
|  | EXPECT_EQ(24, Vec.find_first_unset_in(23, 25)); | 
|  | EXPECT_EQ(24, Vec.find_first_unset_in(24, 25)); | 
|  |  | 
|  | // find last unset | 
|  | EXPECT_EQ(-1, Vec.find_last_unset_in(0, 0)); | 
|  | EXPECT_EQ(-1, Vec.find_last_unset_in(23, 23)); | 
|  | EXPECT_EQ(-1, Vec.find_last_unset_in(6, 9)); | 
|  |  | 
|  | EXPECT_EQ(5, Vec.find_last_unset_in(0, 6)); | 
|  | EXPECT_EQ(4, Vec.find_last_unset_in(0, 5)); | 
|  | EXPECT_EQ(1, Vec.find_last_unset_in(0, 4)); | 
|  | EXPECT_EQ(11, Vec.find_last_unset_in(7, 13)); | 
|  | EXPECT_EQ(24, Vec.find_last_unset_in(18, 25)); | 
|  | EXPECT_EQ(22, Vec.find_last_unset_in(18, 24)); | 
|  | EXPECT_EQ(22, Vec.find_last_unset_in(18, 23)); | 
|  | EXPECT_EQ(20, Vec.find_last_unset_in(18, 22)); | 
|  | EXPECT_EQ(20, Vec.find_last_unset_in(18, 21)); | 
|  | EXPECT_EQ(18, Vec.find_last_unset_in(18, 20)); | 
|  | EXPECT_EQ(18, Vec.find_last_unset_in(18, 19)); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, CompoundAssignment) { | 
|  | TypeParam A; | 
|  | A.resize(10); | 
|  | A.set(4); | 
|  | A.set(7); | 
|  |  | 
|  | TypeParam B; | 
|  | B.resize(50); | 
|  | B.set(5); | 
|  | B.set(18); | 
|  |  | 
|  | A |= B; | 
|  | EXPECT_TRUE(A.test(4)); | 
|  | EXPECT_TRUE(A.test(5)); | 
|  | EXPECT_TRUE(A.test(7)); | 
|  | EXPECT_TRUE(A.test(18)); | 
|  | EXPECT_EQ(4U, A.count()); | 
|  | EXPECT_EQ(50U, A.size()); | 
|  |  | 
|  | B.resize(10); | 
|  | B.set(); | 
|  | B.reset(2); | 
|  | B.reset(7); | 
|  | A &= B; | 
|  | EXPECT_FALSE(A.test(2)); | 
|  | EXPECT_FALSE(A.test(7)); | 
|  | EXPECT_TRUE(A.test(4)); | 
|  | EXPECT_TRUE(A.test(5)); | 
|  | EXPECT_EQ(2U, A.count()); | 
|  | EXPECT_EQ(50U, A.size()); | 
|  |  | 
|  | B.resize(100); | 
|  | B.set(); | 
|  |  | 
|  | A ^= B; | 
|  | EXPECT_TRUE(A.test(2)); | 
|  | EXPECT_TRUE(A.test(7)); | 
|  | EXPECT_EQ(98U, A.count()); | 
|  | EXPECT_EQ(100U, A.size()); | 
|  | } | 
|  |  | 
|  | // Test SmallBitVector operations with mixed big/small representations | 
|  | TYPED_TEST(BitVectorTest, MixedBigSmall) { | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Small &= Big; | 
|  | EXPECT_TRUE(Small.test(0)); | 
|  | EXPECT_EQ(1u, Small.count()); | 
|  | // FIXME BitVector and SmallBitVector behave differently here. | 
|  | // SmallBitVector resizes the LHS to max(LHS.size(), RHS.size()) | 
|  | // but BitVector does not. | 
|  | // EXPECT_EQ(20u, Small.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Big &= Small; | 
|  | EXPECT_TRUE(Big.test(0)); | 
|  | EXPECT_EQ(1u, Big.count()); | 
|  | // FIXME BitVector and SmallBitVector behave differently here. | 
|  | // SmallBitVector resizes the LHS to max(LHS.size(), RHS.size()) | 
|  | // but BitVector does not. | 
|  | // EXPECT_EQ(20u, Big.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Small |= Big; | 
|  | EXPECT_TRUE(Small.test(0)); | 
|  | EXPECT_TRUE(Small.test(1)); | 
|  | EXPECT_TRUE(Small.test(2)); | 
|  | EXPECT_TRUE(Small.test(16)); | 
|  | EXPECT_EQ(4u, Small.count()); | 
|  | EXPECT_EQ(20u, Small.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Big |= Small; | 
|  | EXPECT_TRUE(Big.test(0)); | 
|  | EXPECT_TRUE(Big.test(1)); | 
|  | EXPECT_TRUE(Big.test(2)); | 
|  | EXPECT_TRUE(Big.test(16)); | 
|  | EXPECT_EQ(4u, Big.count()); | 
|  | EXPECT_EQ(20u, Big.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Small ^= Big; | 
|  | EXPECT_TRUE(Small.test(1)); | 
|  | EXPECT_TRUE(Small.test(2)); | 
|  | EXPECT_TRUE(Small.test(16)); | 
|  | EXPECT_EQ(3u, Small.count()); | 
|  | EXPECT_EQ(20u, Small.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Big ^= Small; | 
|  | EXPECT_TRUE(Big.test(1)); | 
|  | EXPECT_TRUE(Big.test(2)); | 
|  | EXPECT_TRUE(Big.test(16)); | 
|  | EXPECT_EQ(3u, Big.count()); | 
|  | EXPECT_EQ(20u, Big.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Small.reset(Big); | 
|  | EXPECT_TRUE(Small.test(1)); | 
|  | EXPECT_EQ(1u, Small.count()); | 
|  | EXPECT_EQ(10u, Small.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  | Big.set(2); | 
|  | Big.set(16); | 
|  |  | 
|  | Big.reset(Small); | 
|  | EXPECT_TRUE(Big.test(2)); | 
|  | EXPECT_TRUE(Big.test(16)); | 
|  | EXPECT_EQ(2u, Big.count()); | 
|  | EXPECT_EQ(20u, Big.size()); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(10); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  |  | 
|  | EXPECT_FALSE(Big == Small); | 
|  | EXPECT_FALSE(Small == Big); | 
|  | Big.set(1); | 
|  | EXPECT_TRUE(Big == Small); | 
|  | EXPECT_TRUE(Small == Big); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(20); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Big.set(1); | 
|  |  | 
|  | EXPECT_FALSE(Small.anyCommon(Big)); | 
|  | EXPECT_FALSE(Big.anyCommon(Small)); | 
|  | Big.set(0); | 
|  | EXPECT_TRUE(Small.anyCommon(Big)); | 
|  | EXPECT_TRUE(Big.anyCommon(Small)); | 
|  | } | 
|  |  | 
|  | { | 
|  | TypeParam Big; | 
|  | TypeParam Small; | 
|  |  | 
|  | Big.reserve(100); | 
|  | Big.resize(10); | 
|  | Small.resize(10); | 
|  |  | 
|  | Small.set(0); | 
|  | Small.set(1); | 
|  | Big.set(0); | 
|  |  | 
|  | EXPECT_TRUE(Small.test(Big)); | 
|  | EXPECT_FALSE(Big.test(Small)); | 
|  | Big.set(1); | 
|  | EXPECT_FALSE(Small.test(Big)); | 
|  | EXPECT_FALSE(Big.test(Small)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, ProxyIndex) { | 
|  | TypeParam Vec(3); | 
|  | EXPECT_TRUE(Vec.none()); | 
|  | Vec[0] = Vec[1] = Vec[2] = true; | 
|  | EXPECT_EQ(Vec.size(), Vec.count()); | 
|  | Vec[2] = Vec[1] = Vec[0] = false; | 
|  | EXPECT_TRUE(Vec.none()); | 
|  | } | 
|  |  | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, PortableBitMask) { | 
|  | TypeParam A; | 
|  | const uint32_t Mask1[] = { 0x80000000, 6, 5 }; | 
|  |  | 
|  | A.resize(10); | 
|  | A.setBitsInMask(Mask1, 1); | 
|  | EXPECT_EQ(10u, A.size()); | 
|  | EXPECT_FALSE(A.test(0)); | 
|  |  | 
|  | A.resize(32); | 
|  | A.setBitsInMask(Mask1, 1); | 
|  | EXPECT_FALSE(A.test(0)); | 
|  | EXPECT_TRUE(A.test(31)); | 
|  | EXPECT_EQ(1u, A.count()); | 
|  |  | 
|  | A.resize(33); | 
|  | A.setBitsInMask(Mask1, 1); | 
|  | EXPECT_EQ(1u, A.count()); | 
|  | A.setBitsInMask(Mask1, 2); | 
|  | EXPECT_EQ(1u, A.count()); | 
|  |  | 
|  | A.resize(34); | 
|  | A.setBitsInMask(Mask1, 2); | 
|  | EXPECT_EQ(2u, A.count()); | 
|  |  | 
|  | A.resize(65); | 
|  | A.setBitsInMask(Mask1, 3); | 
|  | EXPECT_EQ(4u, A.count()); | 
|  |  | 
|  | A.setBitsNotInMask(Mask1, 1); | 
|  | EXPECT_EQ(32u+3u, A.count()); | 
|  |  | 
|  | A.setBitsNotInMask(Mask1, 3); | 
|  | EXPECT_EQ(65u, A.count()); | 
|  |  | 
|  | A.resize(96); | 
|  | EXPECT_EQ(65u, A.count()); | 
|  |  | 
|  | A.clear(); | 
|  | A.resize(128); | 
|  | A.setBitsNotInMask(Mask1, 3); | 
|  | EXPECT_EQ(96u-5u, A.count()); | 
|  |  | 
|  | A.clearBitsNotInMask(Mask1, 1); | 
|  | EXPECT_EQ(64-4u, A.count()); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, BinOps) { | 
|  | TypeParam A; | 
|  | TypeParam B; | 
|  |  | 
|  | A.resize(65); | 
|  | EXPECT_FALSE(A.anyCommon(B)); | 
|  | EXPECT_FALSE(B.anyCommon(B)); | 
|  |  | 
|  | B.resize(64); | 
|  | A.set(64); | 
|  | EXPECT_FALSE(A.anyCommon(B)); | 
|  | EXPECT_FALSE(B.anyCommon(A)); | 
|  |  | 
|  | B.set(63); | 
|  | EXPECT_FALSE(A.anyCommon(B)); | 
|  | EXPECT_FALSE(B.anyCommon(A)); | 
|  |  | 
|  | A.set(63); | 
|  | EXPECT_TRUE(A.anyCommon(B)); | 
|  | EXPECT_TRUE(B.anyCommon(A)); | 
|  |  | 
|  | B.resize(70); | 
|  | B.set(64); | 
|  | B.reset(63); | 
|  | A.resize(64); | 
|  | EXPECT_FALSE(A.anyCommon(B)); | 
|  | EXPECT_FALSE(B.anyCommon(A)); | 
|  | } | 
|  |  | 
|  | typedef std::vector<std::pair<int, int>> RangeList; | 
|  |  | 
|  | template <typename VecType> | 
|  | static inline VecType createBitVector(uint32_t Size, | 
|  | const RangeList &setRanges) { | 
|  | VecType V; | 
|  | V.resize(Size); | 
|  | for (auto &R : setRanges) | 
|  | V.set(R.first, R.second); | 
|  | return V; | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, ShiftOpsSingleWord) { | 
|  | // Test that shift ops work when the desired shift amount is less | 
|  | // than one word. | 
|  |  | 
|  | // 1. Case where the number of bits in the BitVector also fit into a single | 
|  | // word. | 
|  | TypeParam A = createBitVector<TypeParam>(12, {{2, 4}, {8, 10}}); | 
|  | TypeParam B = A; | 
|  |  | 
|  | EXPECT_EQ(4U, A.count()); | 
|  | EXPECT_TRUE(A.test(2)); | 
|  | EXPECT_TRUE(A.test(3)); | 
|  | EXPECT_TRUE(A.test(8)); | 
|  | EXPECT_TRUE(A.test(9)); | 
|  |  | 
|  | A >>= 1; | 
|  | EXPECT_EQ(createBitVector<TypeParam>(12, {{1, 3}, {7, 9}}), A); | 
|  |  | 
|  | A <<= 1; | 
|  | EXPECT_EQ(B, A); | 
|  |  | 
|  | A >>= 10; | 
|  | EXPECT_EQ(createBitVector<TypeParam>(12, {}), A); | 
|  |  | 
|  | A = B; | 
|  | A <<= 10; | 
|  | EXPECT_EQ(createBitVector<TypeParam>(12, {}), A); | 
|  |  | 
|  | // 2. Case where the number of bits in the BitVector do not fit into a single | 
|  | // word. | 
|  |  | 
|  | // 31----------------------------------------------------------------------0 | 
|  | // XXXXXXXX XXXXXXXX XXXXXXXX 00000111 | 11111110 00000000 00001111 11111111 | 
|  | A = createBitVector<TypeParam>(40, {{0, 12}, {25, 35}}); | 
|  | EXPECT_EQ(40U, A.size()); | 
|  | EXPECT_EQ(22U, A.count()); | 
|  |  | 
|  | // 2a. Make sure that left shifting some 1 bits out of the vector works. | 
|  | //   31----------------------------------------------------------------------0 | 
|  | // Before: | 
|  | //   XXXXXXXX XXXXXXXX XXXXXXXX 00000111 | 11111110 00000000 00001111 11111111 | 
|  | // After: | 
|  | //   XXXXXXXX XXXXXXXX XXXXXXXX 11111100 | 00000000 00011111 11111110 00000000 | 
|  | A <<= 9; | 
|  | EXPECT_EQ(createBitVector<TypeParam>(40, {{9, 21}, {34, 40}}), A); | 
|  |  | 
|  | // 2b. Make sure that keeping the number of one bits unchanged works. | 
|  | //   31----------------------------------------------------------------------0 | 
|  | // Before: | 
|  | //   XXXXXXXX XXXXXXXX XXXXXXXX 11111100 | 00000000 00011111 11111110 00000000 | 
|  | // After: | 
|  | //   XXXXXXXX XXXXXXXX XXXXXXXX 00000011 | 11110000 00000000 01111111 11111000 | 
|  | A >>= 6; | 
|  | EXPECT_EQ(createBitVector<TypeParam>(40, {{3, 15}, {28, 34}}), A); | 
|  |  | 
|  | // 2c. Make sure that right shifting some 1 bits out of the vector works. | 
|  | //   31----------------------------------------------------------------------0 | 
|  | // Before: | 
|  | //   XXXXXXXX XXXXXXXX XXXXXXXX 00000011 | 11110000 00000000 01111111 11111000 | 
|  | // After: | 
|  | //   XXXXXXXX XXXXXXXX XXXXXXXX 00000000 | 00000000 11111100 00000000 00011111 | 
|  | A >>= 10; | 
|  | EXPECT_EQ(createBitVector<TypeParam>(40, {{0, 5}, {18, 24}}), A); | 
|  |  | 
|  | // 3. Big test. | 
|  | A = createBitVector<TypeParam>(300, {{1, 30}, {60, 95}, {200, 275}}); | 
|  | A <<= 29; | 
|  | EXPECT_EQ(createBitVector<TypeParam>( | 
|  | 300, {{1 + 29, 30 + 29}, {60 + 29, 95 + 29}, {200 + 29, 300}}), | 
|  | A); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, ShiftOpsMultiWord) { | 
|  | // Test that shift ops work when the desired shift amount is greater than or | 
|  | // equal to the size of a single word. | 
|  | auto A = createBitVector<TypeParam>(300, {{1, 30}, {60, 95}, {200, 275}}); | 
|  |  | 
|  | // Make a copy so we can re-use it later. | 
|  | auto B = A; | 
|  |  | 
|  | // 1. Shift left by an exact multiple of the word size.  This should invoke | 
|  | // only a memmove and no per-word bit operations. | 
|  | A <<= 64; | 
|  | auto Expected = createBitVector<TypeParam>( | 
|  | 300, {{1 + 64, 30 + 64}, {60 + 64, 95 + 64}, {200 + 64, 300}}); | 
|  | EXPECT_EQ(Expected, A); | 
|  |  | 
|  | // 2. Shift left by a non multiple of the word size.  This should invoke both | 
|  | // a memmove and per-word bit operations. | 
|  | A = B; | 
|  | A <<= 93; | 
|  | EXPECT_EQ(createBitVector<TypeParam>( | 
|  | 300, {{1 + 93, 30 + 93}, {60 + 93, 95 + 93}, {200 + 93, 300}}), | 
|  | A); | 
|  |  | 
|  | // 1. Shift right by an exact multiple of the word size.  This should invoke | 
|  | // only a memmove and no per-word bit operations. | 
|  | A = B; | 
|  | A >>= 64; | 
|  | EXPECT_EQ( | 
|  | createBitVector<TypeParam>(300, {{0, 95 - 64}, {200 - 64, 275 - 64}}), A); | 
|  |  | 
|  | // 2. Shift left by a non multiple of the word size.  This should invoke both | 
|  | // a memmove and per-word bit operations. | 
|  | A = B; | 
|  | A >>= 93; | 
|  | EXPECT_EQ( | 
|  | createBitVector<TypeParam>(300, {{0, 95 - 93}, {200 - 93, 275 - 93}}), A); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, RangeOps) { | 
|  | TypeParam A; | 
|  | A.resize(256); | 
|  | A.reset(); | 
|  | A.set(1, 255); | 
|  |  | 
|  | EXPECT_FALSE(A.test(0)); | 
|  | EXPECT_TRUE( A.test(1)); | 
|  | EXPECT_TRUE( A.test(23)); | 
|  | EXPECT_TRUE( A.test(254)); | 
|  | EXPECT_FALSE(A.test(255)); | 
|  |  | 
|  | TypeParam B; | 
|  | B.resize(256); | 
|  | B.set(); | 
|  | B.reset(1, 255); | 
|  |  | 
|  | EXPECT_TRUE( B.test(0)); | 
|  | EXPECT_FALSE(B.test(1)); | 
|  | EXPECT_FALSE(B.test(23)); | 
|  | EXPECT_FALSE(B.test(254)); | 
|  | EXPECT_TRUE( B.test(255)); | 
|  |  | 
|  | TypeParam C; | 
|  | C.resize(3); | 
|  | C.reset(); | 
|  | C.set(0, 1); | 
|  |  | 
|  | EXPECT_TRUE(C.test(0)); | 
|  | EXPECT_FALSE( C.test(1)); | 
|  | EXPECT_FALSE( C.test(2)); | 
|  |  | 
|  | TypeParam D; | 
|  | D.resize(3); | 
|  | D.set(); | 
|  | D.reset(0, 1); | 
|  |  | 
|  | EXPECT_FALSE(D.test(0)); | 
|  | EXPECT_TRUE( D.test(1)); | 
|  | EXPECT_TRUE( D.test(2)); | 
|  |  | 
|  | TypeParam E; | 
|  | E.resize(128); | 
|  | E.reset(); | 
|  | E.set(1, 33); | 
|  |  | 
|  | EXPECT_FALSE(E.test(0)); | 
|  | EXPECT_TRUE( E.test(1)); | 
|  | EXPECT_TRUE( E.test(32)); | 
|  | EXPECT_FALSE(E.test(33)); | 
|  |  | 
|  | TypeParam BufferOverrun; | 
|  | unsigned size = sizeof(unsigned long) * 8; | 
|  | BufferOverrun.resize(size); | 
|  | BufferOverrun.reset(0, size); | 
|  | BufferOverrun.set(0, size); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, CompoundTestReset) { | 
|  | TypeParam A(50, true); | 
|  | TypeParam B(50, false); | 
|  |  | 
|  | TypeParam C(100, true); | 
|  | TypeParam D(100, false); | 
|  |  | 
|  | EXPECT_FALSE(A.test(A)); | 
|  | EXPECT_TRUE(A.test(B)); | 
|  | EXPECT_FALSE(A.test(C)); | 
|  | EXPECT_TRUE(A.test(D)); | 
|  | EXPECT_FALSE(B.test(A)); | 
|  | EXPECT_FALSE(B.test(B)); | 
|  | EXPECT_FALSE(B.test(C)); | 
|  | EXPECT_FALSE(B.test(D)); | 
|  | EXPECT_TRUE(C.test(A)); | 
|  | EXPECT_TRUE(C.test(B)); | 
|  | EXPECT_FALSE(C.test(C)); | 
|  | EXPECT_TRUE(C.test(D)); | 
|  |  | 
|  | A.reset(B); | 
|  | A.reset(D); | 
|  | EXPECT_TRUE(A.all()); | 
|  | A.reset(A); | 
|  | EXPECT_TRUE(A.none()); | 
|  | A.set(); | 
|  | A.reset(C); | 
|  | EXPECT_TRUE(A.none()); | 
|  | A.set(); | 
|  |  | 
|  | C.reset(A); | 
|  | EXPECT_EQ(50, C.find_first()); | 
|  | C.reset(C); | 
|  | EXPECT_TRUE(C.none()); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, MoveConstructor) { | 
|  | TypeParam A(10, true); | 
|  | TypeParam B(std::move(A)); | 
|  | // Check that the move ctor leaves the moved-from object in a valid state. | 
|  | // The following line used to crash. | 
|  | A = B; | 
|  |  | 
|  | TypeParam C(10, true); | 
|  | EXPECT_EQ(C, A); | 
|  | EXPECT_EQ(C, B); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, MoveAssignment) { | 
|  | TypeParam A(10, true); | 
|  | TypeParam B; | 
|  | B = std::move(A); | 
|  | // Check that move assignment leaves the moved-from object in a valid state. | 
|  | // The following line used to crash. | 
|  | A = B; | 
|  |  | 
|  | TypeParam C(10, true); | 
|  | EXPECT_EQ(C, A); | 
|  | EXPECT_EQ(C, B); | 
|  | } | 
|  |  | 
|  | template<class TypeParam> | 
|  | static void testEmpty(const TypeParam &A) { | 
|  | EXPECT_TRUE(A.empty()); | 
|  | EXPECT_EQ((size_t)0, A.size()); | 
|  | EXPECT_EQ((size_t)0, A.count()); | 
|  | EXPECT_FALSE(A.any()); | 
|  | EXPECT_TRUE(A.all()); | 
|  | EXPECT_TRUE(A.none()); | 
|  | EXPECT_EQ(-1, A.find_first()); | 
|  | EXPECT_EQ(A, TypeParam()); | 
|  | } | 
|  |  | 
|  | /// Tests whether BitVector behaves well with Bits==nullptr, Capacity==0 | 
|  | TYPED_TEST(BitVectorTest, EmptyVector) { | 
|  | TypeParam A; | 
|  | testEmpty(A); | 
|  |  | 
|  | TypeParam B; | 
|  | B.reset(); | 
|  | testEmpty(B); | 
|  |  | 
|  | TypeParam C; | 
|  | C.clear(); | 
|  | testEmpty(C); | 
|  |  | 
|  | TypeParam D(A); | 
|  | testEmpty(D); | 
|  |  | 
|  | TypeParam E; | 
|  | E = A; | 
|  | testEmpty(E); | 
|  |  | 
|  | TypeParam F; | 
|  | E.reset(A); | 
|  | testEmpty(E); | 
|  | } | 
|  |  | 
|  | /// Make sure calling getData() is legal even on an empty BitVector | 
|  | TYPED_TEST(BitVectorTest, EmptyVectorGetData) { | 
|  | BitVector A; | 
|  | testEmpty(A); | 
|  | auto B = A.getData(); | 
|  | EXPECT_TRUE(B.empty()); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, Iterators) { | 
|  | TypeParam Singleton(1, true); | 
|  | EXPECT_EQ(std::next(Singleton.set_bits_begin()), Singleton.set_bits_end()); | 
|  |  | 
|  | TypeParam Filled(10, true); | 
|  | EXPECT_NE(Filled.set_bits_begin(), Filled.set_bits_end()); | 
|  | unsigned Counter = 0; | 
|  | for (unsigned Bit : Filled.set_bits()) | 
|  | EXPECT_EQ(Bit, Counter++); | 
|  |  | 
|  | TypeParam Empty; | 
|  | EXPECT_EQ(Empty.set_bits_begin(), Empty.set_bits_end()); | 
|  | int BitCount = 0; | 
|  | for (unsigned Bit : Empty.set_bits()) { | 
|  | (void)Bit; | 
|  | BitCount++; | 
|  | } | 
|  | ASSERT_EQ(BitCount, 0); | 
|  |  | 
|  | TypeParam ToFill(100, false); | 
|  | ToFill.set(0); | 
|  | EXPECT_NE(ToFill.set_bits_begin(), ToFill.set_bits_end()); | 
|  | EXPECT_EQ(++ToFill.set_bits_begin(), ToFill.set_bits_end()); | 
|  | EXPECT_EQ(*ToFill.set_bits_begin(), 0U); | 
|  | ToFill.reset(0); | 
|  | EXPECT_EQ(ToFill.set_bits_begin(), ToFill.set_bits_end()); | 
|  |  | 
|  | const unsigned List[] = {1, 10, 25, 99}; | 
|  | for (unsigned Num : List) | 
|  | ToFill.set(Num); | 
|  | unsigned i = 0; | 
|  | for (unsigned Bit : ToFill.set_bits()) | 
|  | EXPECT_EQ(List[i++], Bit); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, PushBack) { | 
|  | TypeParam Vec(10, false); | 
|  | EXPECT_EQ(-1, Vec.find_first()); | 
|  | EXPECT_EQ(10U, Vec.size()); | 
|  | EXPECT_EQ(0U, Vec.count()); | 
|  | EXPECT_EQ(false, Vec.back()); | 
|  |  | 
|  | Vec.push_back(true); | 
|  | EXPECT_EQ(10, Vec.find_first()); | 
|  | EXPECT_EQ(11U, Vec.size()); | 
|  | EXPECT_EQ(1U, Vec.count()); | 
|  | EXPECT_EQ(true, Vec.back()); | 
|  |  | 
|  | Vec.push_back(false); | 
|  | EXPECT_EQ(10, Vec.find_first()); | 
|  | EXPECT_EQ(12U, Vec.size()); | 
|  | EXPECT_EQ(1U, Vec.count()); | 
|  | EXPECT_EQ(false, Vec.back()); | 
|  |  | 
|  | Vec.push_back(true); | 
|  | EXPECT_EQ(10, Vec.find_first()); | 
|  | EXPECT_EQ(13U, Vec.size()); | 
|  | EXPECT_EQ(2U, Vec.count()); | 
|  | EXPECT_EQ(true, Vec.back()); | 
|  |  | 
|  | // Add a lot of values to cause reallocation. | 
|  | for (int i = 0; i != 100; ++i) { | 
|  | Vec.push_back(true); | 
|  | Vec.push_back(false); | 
|  | } | 
|  | EXPECT_EQ(10, Vec.find_first()); | 
|  | EXPECT_EQ(213U, Vec.size()); | 
|  | EXPECT_EQ(102U, Vec.count()); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, PopBack) { | 
|  | TypeParam Vec(10, true); | 
|  | EXPECT_EQ(10U, Vec.size()); | 
|  | EXPECT_EQ(10U, Vec.count()); | 
|  | EXPECT_EQ(true, Vec.back()); | 
|  |  | 
|  | Vec.pop_back(); | 
|  | EXPECT_EQ(9U, Vec.size()); | 
|  | EXPECT_EQ(9U, Vec.count()); | 
|  | EXPECT_EQ(true, Vec.back()); | 
|  |  | 
|  | Vec.push_back(false); | 
|  | EXPECT_EQ(10U, Vec.size()); | 
|  | EXPECT_EQ(9U, Vec.count()); | 
|  | EXPECT_EQ(false, Vec.back()); | 
|  |  | 
|  | Vec.pop_back(); | 
|  | EXPECT_EQ(9U, Vec.size()); | 
|  | EXPECT_EQ(9U, Vec.count()); | 
|  | EXPECT_EQ(true, Vec.back()); | 
|  | } | 
|  |  | 
|  | TYPED_TEST(BitVectorTest, DenseSet) { | 
|  | DenseSet<TypeParam> Set; | 
|  | TypeParam A(10, true); | 
|  | auto I = Set.insert(A); | 
|  | EXPECT_EQ(true, I.second); | 
|  |  | 
|  | TypeParam B(5, true); | 
|  | I = Set.insert(B); | 
|  | EXPECT_EQ(true, I.second); | 
|  |  | 
|  | TypeParam C(20, false); | 
|  | C.set(19); | 
|  | I = Set.insert(C); | 
|  | EXPECT_EQ(true, I.second); | 
|  |  | 
|  | #if LLVM_ENABLE_ABI_BREAKING_CHECKS | 
|  | TypeParam D; | 
|  | EXPECT_DEATH(Set.insert(D), | 
|  | "Empty/Tombstone value shouldn't be inserted into map!"); | 
|  | #endif | 
|  |  | 
|  | EXPECT_EQ(3U, Set.size()); | 
|  | EXPECT_EQ(1U, Set.count(A)); | 
|  | EXPECT_EQ(1U, Set.count(B)); | 
|  | EXPECT_EQ(1U, Set.count(C)); | 
|  |  | 
|  | EXPECT_EQ(true, Set.erase(B)); | 
|  | EXPECT_EQ(2U, Set.size()); | 
|  |  | 
|  | EXPECT_EQ(true, Set.erase(C)); | 
|  | EXPECT_EQ(1U, Set.size()); | 
|  |  | 
|  | EXPECT_EQ(true, Set.erase(A)); | 
|  | EXPECT_EQ(0U, Set.size()); | 
|  | } | 
|  |  | 
|  | /// Test that capacity doesn't affect hashing. | 
|  | TYPED_TEST(BitVectorTest, DenseMapHashing) { | 
|  | using DMI = DenseMapInfo<TypeParam>; | 
|  | { | 
|  | TypeParam A; | 
|  | A.resize(200); | 
|  | A.set(100); | 
|  |  | 
|  | TypeParam B; | 
|  | B.resize(200); | 
|  | B.set(100); | 
|  | B.reserve(1000); | 
|  |  | 
|  | EXPECT_EQ(DMI::getHashValue(A), DMI::getHashValue(B)); | 
|  | } | 
|  | { | 
|  | TypeParam A; | 
|  | A.resize(20); | 
|  | A.set(10); | 
|  |  | 
|  | TypeParam B; | 
|  | B.resize(20); | 
|  | B.set(10); | 
|  | B.reserve(1000); | 
|  |  | 
|  | EXPECT_EQ(DMI::getHashValue(A), DMI::getHashValue(B)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(BitVectoryTest, Apply) { | 
|  | for (int i = 0; i < 2; ++i) { | 
|  | int j = i * 100 + 3; | 
|  |  | 
|  | const BitVector x = | 
|  | createBitVector<BitVector>(j + 5, {{i, i + 1}, {j - 1, j}}); | 
|  | const BitVector y = createBitVector<BitVector>(j + 5, {{i, j}}); | 
|  | const BitVector z = | 
|  | createBitVector<BitVector>(j + 5, {{i + 1, i + 2}, {j, j + 1}}); | 
|  |  | 
|  | auto op0 = [](auto x) { return ~x; }; | 
|  | BitVector expected0 = x; | 
|  | expected0.flip(); | 
|  | BitVector out0(j - 2); | 
|  | BitVector::apply(op0, out0, x); | 
|  | EXPECT_EQ(out0, expected0); | 
|  |  | 
|  | auto op1 = [](auto x, auto y) { return x & ~y; }; | 
|  | BitVector expected1 = x; | 
|  | expected1.reset(y); | 
|  | BitVector out1; | 
|  | BitVector::apply(op1, out1, x, y); | 
|  | EXPECT_EQ(out1, expected1); | 
|  |  | 
|  | auto op2 = [](auto x, auto y, auto z) { return (x ^ ~y) | z; }; | 
|  | BitVector expected2 = y; | 
|  | expected2.flip(); | 
|  | expected2 ^= x; | 
|  | expected2 |= z; | 
|  | BitVector out2(j + 5); | 
|  | BitVector::apply(op2, out2, x, y, z); | 
|  | EXPECT_EQ(out2, expected2); | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | } // namespace |