blob: 8e6a0abe35283bf161c41b13f17da1bea02e3954 [file]
/*
* Copyright 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <gui/BitSet.h>
namespace android {
TEST(BitSet, DefaultConstructor) {
BitSet<10> bs;
ASSERT_EQ(bs.size(), 10u);
ASSERT_TRUE(bs.none());
ASSERT_FALSE(bs.any());
ASSERT_FALSE(bs);
}
TEST(BitSet, InitializerListConstructor) {
BitSet<64> bs{1, 10, 63};
ASSERT_EQ(bs.count(), 3u);
ASSERT_TRUE(bs.test(1));
ASSERT_TRUE(bs.test(10));
ASSERT_TRUE(bs.test(63));
ASSERT_FALSE(bs.test(0));
ASSERT_FALSE(bs.test(2));
// Out of bounds in initializer list
EXPECT_ANY_THROW((BitSet<5>{5}));
}
TEST(BitSet, SetAndTest) {
BitSet<64> bs;
bs.set(10);
ASSERT_TRUE(bs.test(10));
ASSERT_TRUE(bs[10]);
ASSERT_FALSE(bs.test(11));
ASSERT_TRUE(bs.any());
ASSERT_TRUE(bs);
ASSERT_EQ(bs.count(), 1u);
bs.set(63);
ASSERT_TRUE(bs.test(63));
ASSERT_EQ(bs.count(), 2u);
}
TEST(BitSet, SetAll) {
BitSet<128> bs;
bs.set();
ASSERT_TRUE(bs.all());
ASSERT_EQ(bs.count(), 128u);
ASSERT_TRUE(bs.test(0));
ASSERT_TRUE(bs.test(127));
}
TEST(BitSet, Reset) {
BitSet<32> bs;
bs.set();
bs.reset(5);
ASSERT_FALSE(bs.test(5));
ASSERT_EQ(bs.count(), 31u);
bs.reset();
ASSERT_TRUE(bs.none());
ASSERT_EQ(bs.count(), 0u);
}
TEST(BitSet, Flip) {
BitSet<16> bs;
bs.flip(3);
ASSERT_TRUE(bs.test(3));
ASSERT_EQ(bs.count(), 1u);
bs.flip();
ASSERT_FALSE(bs.test(3));
ASSERT_TRUE(bs.test(0));
ASSERT_TRUE(bs.test(15));
ASSERT_EQ(bs.count(), 15u);
}
TEST(BitSet, OperatorBool) {
BitSet<8> bs;
ASSERT_FALSE(bool(bs));
bs.set(0);
ASSERT_TRUE(bool(bs));
bs.reset(0);
ASSERT_FALSE(bool(bs));
}
TEST(BitSet, OperatorEquals) {
BitSet<100> bs1;
BitSet<100> bs2;
ASSERT_TRUE(bs1 == bs2);
ASSERT_FALSE(bs1 != bs2);
bs1.set(50);
ASSERT_FALSE(bs1 == bs2);
ASSERT_TRUE(bs1 != bs2);
bs2.set(50);
ASSERT_TRUE(bs1 == bs2);
}
TEST(BitSet, CopyConstructorAndAssignment) {
BitSet<64> bs1;
bs1.set(10).set(20);
// Copy constructor test
BitSet<64> bs2(bs1);
ASSERT_EQ(bs1.count(), bs2.count());
ASSERT_TRUE(bs2.test(10));
ASSERT_TRUE(bs2.test(20));
ASSERT_TRUE(bs1 == bs2);
// Assignment operator test
BitSet<64> bs3;
bs3.set(5);
bs3 = bs1;
ASSERT_EQ(bs1.count(), bs3.count());
ASSERT_TRUE(bs3.test(10));
ASSERT_TRUE(bs3.test(20));
ASSERT_FALSE(bs3.test(5));
ASSERT_TRUE(bs1 == bs3);
}
TEST(BitSet, BitwiseOperators) {
BitSet<32> bs1;
bs1.set(1).set(2);
BitSet<32> bs2;
bs2.set(2).set(3);
BitSet<32> and_res = bs1 & bs2;
ASSERT_FALSE(and_res.test(1));
ASSERT_TRUE(and_res.test(2));
ASSERT_FALSE(and_res.test(3));
BitSet<32> or_res = bs1 | bs2;
ASSERT_TRUE(or_res.test(1));
ASSERT_TRUE(or_res.test(2));
ASSERT_TRUE(or_res.test(3));
BitSet<32> xor_res = bs1 ^ bs2;
ASSERT_TRUE(xor_res.test(1));
ASSERT_FALSE(xor_res.test(2));
ASSERT_TRUE(xor_res.test(3));
BitSet<32> not_res = ~bs1;
ASSERT_FALSE(not_res.test(1));
ASSERT_FALSE(not_res.test(2));
ASSERT_TRUE(not_res.test(0));
ASSERT_TRUE(not_res.test(31));
}
TEST(BitSet, BitwiseAssignmentOperators) {
BitSet<32> bs1;
bs1.set(1).set(2);
BitSet<32> bs2;
bs2.set(2).set(3);
bs1 &= bs2;
ASSERT_FALSE(bs1.test(1));
ASSERT_TRUE(bs1.test(2));
ASSERT_FALSE(bs1.test(3));
bs1 |= bs2;
ASSERT_FALSE(bs1.test(1));
ASSERT_TRUE(bs1.test(2));
ASSERT_TRUE(bs1.test(3));
bs1 ^= bs2;
ASSERT_FALSE(bs1.test(1));
ASSERT_FALSE(bs1.test(2));
ASSERT_FALSE(bs1.test(3));
}
TEST(BitSet, ShiftOperators) {
BitSet<128> bs;
bs.set(10).set(70);
BitSet<128> left = bs << 5;
ASSERT_TRUE(left.test(15));
ASSERT_TRUE(left.test(75));
ASSERT_FALSE(left.test(10));
ASSERT_FALSE(left.test(70));
BitSet<128> right = bs >> 5;
ASSERT_TRUE(right.test(5));
ASSERT_TRUE(right.test(65));
ASSERT_FALSE(right.test(10));
ASSERT_FALSE(right.test(70));
BitSet<128> bs_shift;
bs_shift.set(127);
ASSERT_EQ((bs_shift << 1).count(), 0u);
bs_shift.reset().set(0);
ASSERT_EQ((bs_shift >> 1).count(), 0u);
}
TEST(BitSet, ShiftAssignmentOperators) {
BitSet<128> bs;
bs.set(10).set(70);
bs <<= 5;
ASSERT_TRUE(bs.test(15));
ASSERT_TRUE(bs.test(75));
ASSERT_FALSE(bs.test(10));
ASSERT_FALSE(bs.test(70));
bs >>= 10;
ASSERT_TRUE(bs.test(5));
ASSERT_TRUE(bs.test(65));
ASSERT_FALSE(bs.test(15));
ASSERT_FALSE(bs.test(75));
bs <<= 1000;
ASSERT_EQ(bs.count(), 0u);
}
TEST(BitSet, ReferenceProxy) {
BitSet<20> bs;
bs[5] = true;
ASSERT_TRUE(bs.test(5));
bs[5] = false;
ASSERT_FALSE(bs.test(5));
bs[10] = true;
bs[15] = bs[10];
ASSERT_TRUE(bs.test(15));
bs[10] = ~bs[15];
ASSERT_FALSE(bs.test(10));
bool val = bs[15];
ASSERT_TRUE(val);
bs[15].flip();
ASSERT_FALSE(bs.test(15));
}
TEST(BitSet, ToString) {
BitSet<5> bs;
bs.set(1).set(3);
// position 0 is rightmost bit (index 4 in string length 5)
// 43210
// 01010
ASSERT_EQ(bs.to_string(), "01010");
ASSERT_EQ(bs.to_string('F', 'T'), "FTFTF");
}
TEST(BitSet, GetArray) {
BitSet<65> bs;
bs.set(0).set(64);
const auto* arr = bs.data();
ASSERT_EQ(bs.dataSize(), 16u);
ASSERT_EQ(arr[0], std::byte{1}); // bit 0
ASSERT_EQ(arr[8], std::byte{1}); // bit 64
auto* mut_arr = bs.data();
mut_arr[0] = std::byte{0};
ASSERT_FALSE(bs.test(0));
}
TEST(BitSet, OutOfBounds) {
BitSet<10> bs;
EXPECT_ANY_THROW(bs.set(10));
EXPECT_ANY_THROW(bs.reset(10));
EXPECT_ANY_THROW(bs.flip(10));
EXPECT_ANY_THROW(bs.test(10));
}
TEST(BitSet, CleanUnusedBits) {
BitSet<10> bs;
bs.set(); // should only set bottom 10 bits of the 64-bit word
ASSERT_EQ(bs.dataSize(), 8u);
const uint64_t* arr = reinterpret_cast<const uint64_t*>(bs.data());
ASSERT_EQ(arr[0], (1ull << 10) - 1);
bs.flip(); // should clear bottom 10 bits, upper 54 bits should remain 0
ASSERT_EQ(arr[0], 0ull);
ASSERT_TRUE(bs.none());
bs.set(); // set 10 bits again
BitSet<10> not_bs = ~bs; // complement should flip bottom 10 bits, keep upper 54 clean
ASSERT_TRUE(not_bs.none());
}
} // namespace android