Path: blob/main_old/src/common/bitset_utils_unittest.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// bitset_utils_unittest:6// Tests bitset helpers and custom classes.7//89#include <array>1011#include <gtest/gtest.h>1213#include "common/bitset_utils.h"1415using namespace angle;1617namespace18{19template <typename T>20class BitSetTest : public testing::Test21{22protected:23T mBits;24typedef T BitSet;25};2627using BitSetTypes = ::testing::Types<BitSet<12>, BitSet32<12>, BitSet64<12>>;28TYPED_TEST_SUITE(BitSetTest, BitSetTypes);2930TYPED_TEST(BitSetTest, Basic)31{32EXPECT_EQ(TypeParam::Zero().bits(), 0u);3334TypeParam mBits = this->mBits;35EXPECT_FALSE(mBits.all());36EXPECT_FALSE(mBits.any());37EXPECT_TRUE(mBits.none());38EXPECT_EQ(mBits.count(), 0u);3940// Set every bit to 1.41for (size_t i = 0; i < mBits.size(); ++i)42{43mBits.set(i);4445EXPECT_EQ(mBits.all(), i + 1 == mBits.size());46EXPECT_TRUE(mBits.any());47EXPECT_FALSE(mBits.none());48EXPECT_EQ(mBits.count(), i + 1);49}5051// Reset every other bit to 0.52for (size_t i = 0; i < mBits.size(); i += 2)53{54mBits.reset(i);5556EXPECT_FALSE(mBits.all());57EXPECT_TRUE(mBits.any());58EXPECT_FALSE(mBits.none());59EXPECT_EQ(mBits.count(), mBits.size() - i / 2 - 1);60}6162// Flip all bits.63for (size_t i = 0; i < mBits.size(); ++i)64{65mBits.flip(i);6667EXPECT_FALSE(mBits.all());68EXPECT_TRUE(mBits.any());69EXPECT_FALSE(mBits.none());70EXPECT_EQ(mBits.count(), mBits.size() / 2 + (i % 2 == 0));71}7273// Make sure the bit pattern is what we expect at this point.74for (size_t i = 0; i < mBits.size(); ++i)75{76EXPECT_EQ(mBits.test(i), i % 2 == 0);77EXPECT_EQ(static_cast<bool>(mBits[i]), i % 2 == 0);78}7980// Test that flip, set and reset all bits at once work.81mBits.flip();82EXPECT_FALSE(mBits.all());83EXPECT_TRUE(mBits.any());84EXPECT_FALSE(mBits.none());85EXPECT_EQ(mBits.count(), mBits.size() / 2);86EXPECT_EQ(mBits.first(), 1u);8788mBits.set();89EXPECT_TRUE(mBits.all());90EXPECT_TRUE(mBits.any());91EXPECT_FALSE(mBits.none());92EXPECT_EQ(mBits.count(), mBits.size());93EXPECT_EQ(mBits.first(), 0u);9495mBits.reset();96EXPECT_FALSE(mBits.all());97EXPECT_FALSE(mBits.any());98EXPECT_TRUE(mBits.none());99EXPECT_EQ(mBits.count(), 0u);100101// Test that out-of-bound sets don't modify the bitset102constexpr uint32_t kMask = (1 << 12) - 1;103104EXPECT_EQ(mBits.set(12).bits() & ~kMask, 0u);105EXPECT_EQ(mBits.set(13).bits() & ~kMask, 0u);106EXPECT_EQ(mBits.flip(12).bits() & ~kMask, 0u);107EXPECT_EQ(mBits.flip(13).bits() & ~kMask, 0u);108}109110TYPED_TEST(BitSetTest, BitwiseOperators)111{112TypeParam mBits = this->mBits;113// Use a value that has a 1 in the 12th and 13th bits, to make sure masking to exactly 12 bits114// does not have an off-by-one error.115constexpr uint32_t kSelfValue = 0xF9E4;116constexpr uint32_t kOtherValue = 0x5C6A;117118constexpr uint32_t kMask = (1 << 12) - 1;119constexpr uint32_t kSelfMaskedValue = kSelfValue & kMask;120constexpr uint32_t kOtherMaskedValue = kOtherValue & kMask;121122constexpr uint32_t kShift = 3;123constexpr uint32_t kSelfShiftedLeft = kSelfMaskedValue << kShift & kMask;124constexpr uint32_t kSelfShiftedRight = kSelfMaskedValue >> kShift & kMask;125126mBits |= kSelfValue;127typename TestFixture::BitSet other(kOtherValue);128typename TestFixture::BitSet anded(kSelfMaskedValue & kOtherMaskedValue);129typename TestFixture::BitSet ored(kSelfMaskedValue | kOtherMaskedValue);130typename TestFixture::BitSet xored(kSelfMaskedValue ^ kOtherMaskedValue);131132EXPECT_EQ(mBits.bits(), kSelfMaskedValue);133EXPECT_EQ(other.bits(), kOtherMaskedValue);134135EXPECT_EQ(mBits & other, anded);136EXPECT_EQ(mBits | other, ored);137EXPECT_EQ(mBits ^ other, xored);138139EXPECT_NE(mBits, other);140EXPECT_NE(anded, ored);141EXPECT_NE(anded, xored);142EXPECT_NE(ored, xored);143144mBits &= other;145EXPECT_EQ(mBits, anded);146147mBits |= ored;148EXPECT_EQ(mBits, ored);149150mBits ^= other;151mBits ^= anded;152EXPECT_EQ(mBits, typename TestFixture::BitSet(kSelfValue));153154EXPECT_EQ(mBits << kShift, typename TestFixture::BitSet(kSelfShiftedLeft));155EXPECT_EQ(mBits >> kShift, typename TestFixture::BitSet(kSelfShiftedRight));156157mBits <<= kShift;158EXPECT_EQ(mBits, typename TestFixture::BitSet(kSelfShiftedLeft));159EXPECT_EQ(mBits.bits() & ~kMask, 0u);160161mBits = typename TestFixture::BitSet(kSelfValue);162mBits >>= kShift;163EXPECT_EQ(mBits, typename TestFixture::BitSet(kSelfShiftedRight));164EXPECT_EQ(mBits.bits() & ~kMask, 0u);165166mBits |= kSelfMaskedValue;167EXPECT_EQ(mBits.bits() & ~kMask, 0u);168mBits ^= kOtherMaskedValue;169EXPECT_EQ(mBits.bits() & ~kMask, 0u);170}171172template <typename T>173class BitSetIteratorTest : public testing::Test174{175protected:176T mStateBits;177typedef T BitSet;178};179180using BitSetIteratorTypes = ::testing::Types<BitSet<40>, BitSet64<40>>;181TYPED_TEST_SUITE(BitSetIteratorTest, BitSetIteratorTypes);182183// Simple iterator test.184TYPED_TEST(BitSetIteratorTest, Iterator)185{186TypeParam mStateBits = this->mStateBits;187std::set<size_t> originalValues;188originalValues.insert(2);189originalValues.insert(6);190originalValues.insert(8);191originalValues.insert(35);192193for (size_t value : originalValues)194{195mStateBits.set(value);196}197198std::set<size_t> readValues;199for (size_t bit : mStateBits)200{201EXPECT_EQ(1u, originalValues.count(bit));202EXPECT_EQ(0u, readValues.count(bit));203readValues.insert(bit);204}205206EXPECT_EQ(originalValues.size(), readValues.size());207}208209// Ensure lsb->msb iteration order.210TYPED_TEST(BitSetIteratorTest, IterationOrder)211{212TypeParam mStateBits = this->mStateBits;213const std::array<size_t, 8> writeOrder = {20, 25, 16, 31, 10, 14, 36, 19};214const std::array<size_t, 8> fetchOrder = {10, 14, 16, 19, 20, 25, 31, 36};215216for (size_t value : writeOrder)217{218mStateBits.set(value);219}220EXPECT_EQ(writeOrder.size(), mStateBits.count());221222size_t i = 0;223for (size_t bit : mStateBits)224{225EXPECT_EQ(fetchOrder[i], bit);226i++;227}228EXPECT_EQ(fetchOrder.size(), mStateBits.count());229}230231// Test an empty iterator.232TYPED_TEST(BitSetIteratorTest, EmptySet)233{234TypeParam mStateBits = this->mStateBits;235// We don't use the FAIL gtest macro here since it returns immediately,236// causing an unreachable code warning in MSVS237bool sawBit = false;238for (size_t bit : mStateBits)239{240sawBit = true;241ANGLE_UNUSED_VARIABLE(bit);242}243EXPECT_FALSE(sawBit);244}245246// Test iterating a result of combining two bitsets.247TYPED_TEST(BitSetIteratorTest, NonLValueBitset)248{249TypeParam mStateBits = this->mStateBits;250typename TestFixture::BitSet otherBits;251252mStateBits.set(1);253mStateBits.set(2);254mStateBits.set(3);255mStateBits.set(4);256257otherBits.set(0);258otherBits.set(1);259otherBits.set(3);260otherBits.set(5);261262std::set<size_t> seenBits;263264typename TestFixture::BitSet maskedBits = (mStateBits & otherBits);265for (size_t bit : maskedBits)266{267EXPECT_EQ(0u, seenBits.count(bit));268seenBits.insert(bit);269EXPECT_TRUE(mStateBits[bit]);270EXPECT_TRUE(otherBits[bit]);271}272273EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());274}275276// Test bit assignments.277TYPED_TEST(BitSetIteratorTest, BitAssignment)278{279TypeParam mStateBits = this->mStateBits;280std::set<size_t> originalValues;281originalValues.insert(2);282originalValues.insert(6);283originalValues.insert(8);284originalValues.insert(35);285286for (size_t value : originalValues)287{288(mStateBits[value] = false) = true;289}290291for (size_t value : originalValues)292{293EXPECT_TRUE(mStateBits.test(value));294}295}296297// Tests adding bits to the iterator during iteration.298TYPED_TEST(BitSetIteratorTest, SetLaterBit)299{300TypeParam mStateBits = this->mStateBits;301std::set<size_t> expectedValues = {0, 1, 3, 5, 6, 7, 9, 35};302mStateBits.set(0);303mStateBits.set(1);304305std::set<size_t> actualValues;306307for (auto iter = mStateBits.begin(), end = mStateBits.end(); iter != end; ++iter)308{309if (*iter == 1)310{311iter.setLaterBit(3);312iter.setLaterBit(5);313}314if (*iter == 5)315{316iter.setLaterBit(6);317iter.setLaterBit(7);318iter.setLaterBit(9);319iter.setLaterBit(35);320}321322actualValues.insert(*iter);323}324325EXPECT_EQ(expectedValues, actualValues);326}327328// Tests removing bits from the iterator during iteration.329TYPED_TEST(BitSetIteratorTest, ResetLaterBit)330{331TypeParam mStateBits = this->mStateBits;332std::set<size_t> expectedValues = {1, 3, 5, 7, 9};333334for (size_t index = 1; index <= 9; ++index)335mStateBits.set(index);336337std::set<size_t> actualValues;338339for (auto iter = mStateBits.begin(), end = mStateBits.end(); iter != end; ++iter)340{341if (*iter == 1)342{343iter.resetLaterBit(2);344iter.resetLaterBit(4);345iter.resetLaterBit(6);346iter.resetLaterBit(8);347}348349actualValues.insert(*iter);350}351352EXPECT_EQ(expectedValues, actualValues);353}354355// Tests adding bitsets to the iterator during iteration.356TYPED_TEST(BitSetIteratorTest, SetLaterBits)357{358TypeParam mStateBits = this->mStateBits;359std::set<size_t> expectedValues = {1, 2, 3, 4, 5, 7, 9};360mStateBits.set(1);361mStateBits.set(2);362mStateBits.set(3);363364TypeParam laterBits;365laterBits.set(4);366laterBits.set(5);367laterBits.set(7);368laterBits.set(9);369370std::set<size_t> actualValues;371372for (auto iter = mStateBits.begin(), end = mStateBits.end(); iter != end; ++iter)373{374if (*iter == 3)375{376iter.setLaterBits(laterBits);377}378379EXPECT_EQ(actualValues.count(*iter), 0u);380actualValues.insert(*iter);381}382383EXPECT_EQ(expectedValues, actualValues);384}385386template <typename T>387class BitSetArrayTest : public testing::Test388{389protected:390T mBitSet;391};392393using BitSetArrayTypes =394::testing::Types<BitSetArray<65>, BitSetArray<128>, BitSetArray<130>, BitSetArray<511>>;395TYPED_TEST_SUITE(BitSetArrayTest, BitSetArrayTypes);396397TYPED_TEST(BitSetArrayTest, BasicTest)398{399TypeParam &mBits = this->mBitSet;400401EXPECT_FALSE(mBits.all());402EXPECT_FALSE(mBits.any());403EXPECT_TRUE(mBits.none());404EXPECT_EQ(mBits.count(), 0u);405EXPECT_EQ(mBits.bits(0), 0u);406407// Verify set on a single bit408mBits.set(45);409for (auto bit : mBits)410{411EXPECT_EQ(bit, 45u);412}413414EXPECT_EQ(mBits.first(), 45u);415EXPECT_EQ(mBits.last(), 45u);416417mBits.reset(45);418419// Set every bit to 1.420for (size_t i = 0; i < mBits.size(); ++i)421{422mBits.set(i);423424EXPECT_EQ(mBits.all(), i + 1 == mBits.size());425EXPECT_TRUE(mBits.any());426EXPECT_FALSE(mBits.none());427EXPECT_EQ(mBits.count(), i + 1);428}429430// Reset odd bits to 0.431for (size_t i = 1; i < mBits.size(); i += 2)432{433mBits.reset(i);434435EXPECT_FALSE(mBits.all());436EXPECT_TRUE(mBits.any());437EXPECT_FALSE(mBits.none());438EXPECT_EQ(mBits.count(), mBits.size() - i / 2 - 1);439}440441// Make sure the bit pattern is what we expect at this point.442// All even bits should be set443for (size_t i = 0; i < mBits.size(); ++i)444{445EXPECT_EQ(mBits.test(i), i % 2 == 0);446EXPECT_EQ(static_cast<bool>(mBits[i]), i % 2 == 0);447}448449// Reset everything.450mBits.reset();451EXPECT_FALSE(mBits.all());452EXPECT_FALSE(mBits.any());453EXPECT_TRUE(mBits.none());454EXPECT_EQ(mBits.count(), 0u);455456// Test intersection logic457TypeParam testBitSet;458testBitSet.set(1);459EXPECT_EQ(testBitSet.bits(0), (1ul << 1ul));460testBitSet.set(3);461EXPECT_EQ(testBitSet.bits(0), (1ul << 1ul) | (1ul << 3ul));462testBitSet.set(5);463EXPECT_EQ(testBitSet.bits(0), (1ul << 1ul) | (1ul << 3ul) | (1ul << 5ul));464EXPECT_FALSE(mBits.intersects(testBitSet));465mBits.set(3);466EXPECT_TRUE(mBits.intersects(testBitSet));467mBits.set(4);468EXPECT_TRUE(mBits.intersects(testBitSet));469mBits.reset(3);470EXPECT_FALSE(mBits.intersects(testBitSet));471testBitSet.set(4);472EXPECT_TRUE(mBits.intersects(testBitSet));473474// Test that flip works.475// Reset everything.476mBits.reset();477EXPECT_EQ(mBits.count(), 0u);478mBits.flip();479EXPECT_EQ(mBits.count(), mBits.size());480481// Test operators482483// Assignment operators - "=", "&=", "|=" and "^="484mBits.reset();485mBits = testBitSet;486for (auto bit : testBitSet)487{488EXPECT_TRUE(mBits.test(bit));489}490491mBits &= testBitSet;492for (auto bit : testBitSet)493{494EXPECT_TRUE(mBits.test(bit));495}496EXPECT_EQ(mBits.count(), testBitSet.count());497498mBits.reset();499mBits |= testBitSet;500for (auto bit : testBitSet)501{502EXPECT_TRUE(mBits.test(bit));503}504505mBits ^= testBitSet;506EXPECT_TRUE(mBits.none());507508// Bitwise operators - "&", "|" and "^"509std::set<std::size_t> bits1 = {0, 45, 60};510std::set<std::size_t> bits2 = {5, 45, 50, 63};511std::set<std::size_t> bits1Andbits2 = {45};512std::set<std::size_t> bits1Orbits2 = {0, 5, 45, 50, 60, 63};513std::set<std::size_t> bits1Xorbits2 = {0, 5, 50, 60, 63};514std::set<std::size_t> actualValues;515TypeParam testBitSet1;516TypeParam testBitSet2;517518for (std::size_t bit : bits1)519{520testBitSet1.set(bit);521}522for (std::size_t bit : bits2)523{524testBitSet2.set(bit);525}526527EXPECT_EQ(testBitSet1.first(), 0u);528EXPECT_EQ(testBitSet1.last(), 60u);529530EXPECT_EQ(testBitSet2.first(), 5u);531EXPECT_EQ(testBitSet2.last(), 63u);532533actualValues.clear();534for (auto bit : (testBitSet1 & testBitSet2))535{536actualValues.insert(bit);537}538EXPECT_EQ(bits1Andbits2, actualValues);539540actualValues.clear();541for (auto bit : (testBitSet1 | testBitSet2))542{543actualValues.insert(bit);544}545EXPECT_EQ(bits1Orbits2, actualValues);546547actualValues.clear();548for (auto bit : (testBitSet1 ^ testBitSet2))549{550actualValues.insert(bit);551}552EXPECT_EQ(bits1Xorbits2, actualValues);553554// Relational operators - "==" and "!="555EXPECT_FALSE(testBitSet1 == testBitSet2);556EXPECT_TRUE(testBitSet1 != testBitSet2);557558// Unary operators - "~" and "[]"559mBits.reset();560mBits = ~testBitSet;561for (auto bit : mBits)562{563EXPECT_FALSE(testBitSet.test(bit));564}565EXPECT_EQ(mBits.count(), (mBits.size() - testBitSet.count()));566567mBits.reset();568for (auto bit : testBitSet)569{570mBits[bit] = true;571}572for (auto bit : mBits)573{574EXPECT_TRUE(testBitSet.test(bit));575}576}577578// Unit test for angle::Bit579TEST(Bit, Test)580{581EXPECT_EQ(Bit<uint32_t>(0), 1u);582EXPECT_EQ(Bit<uint32_t>(1), 2u);583EXPECT_EQ(Bit<uint32_t>(2), 4u);584EXPECT_EQ(Bit<uint32_t>(3), 8u);585EXPECT_EQ(Bit<uint32_t>(31), 0x8000'0000u);586EXPECT_EQ(Bit<uint64_t>(63), static_cast<uint64_t>(0x8000'0000'0000'0000llu));587}588589// Unit test for angle::BitMask590TEST(BitMask, Test)591{592EXPECT_EQ(BitMask<uint32_t>(1), 1u);593EXPECT_EQ(BitMask<uint32_t>(2), 3u);594EXPECT_EQ(BitMask<uint32_t>(3), 7u);595EXPECT_EQ(BitMask<uint32_t>(31), 0x7FFF'FFFFu);596EXPECT_EQ(BitMask<uint32_t>(32), 0xFFFF'FFFFu);597EXPECT_EQ(BitMask<uint64_t>(63), static_cast<uint64_t>(0x7FFF'FFFF'FFFF'FFFFllu));598EXPECT_EQ(BitMask<uint64_t>(64), static_cast<uint64_t>(0xFFFF'FFFF'FFFF'FFFFllu));599}600} // anonymous namespace601602603