mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
7d235f4fd0
Also do some basic cleanup: capitalize first letters, add `.` at the end of the sentences, and so on.
221 lines
4.6 KiB
C++
221 lines
4.6 KiB
C++
/// \file LazySmallBitVector.cpp
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include <algorithm>
|
|
#include <cstdint>
|
|
#include <iterator>
|
|
#include <vector>
|
|
|
|
#define BOOST_TEST_MODULE LazySmallBitVector
|
|
bool init_unit_test();
|
|
#include "boost/test/unit_test.hpp"
|
|
|
|
#include "revng/ADT/LazySmallBitVector.h"
|
|
#include "revng/UnitTestHelpers/UnitTestHelpers.h"
|
|
|
|
static const unsigned FirstLargeBit = sizeof(uintptr_t) * CHAR_BIT;
|
|
|
|
// The following types don't have a << operator
|
|
BOOST_TEST_DONT_PRINT_LOG_VALUE(LazySmallBitVector)
|
|
BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<unsigned>)
|
|
|
|
BOOST_AUTO_TEST_CASE(TestEmpty) {
|
|
LazySmallBitVector Empty;
|
|
BOOST_TEST(Empty.isZero());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestSetAndRead) {
|
|
LazySmallBitVector BitVector;
|
|
|
|
// Test small
|
|
BitVector.set(0);
|
|
BOOST_TEST(BitVector.requiredBits() == 1U);
|
|
BOOST_TEST(BitVector[0] == true);
|
|
BOOST_TEST(BitVector[1] == false);
|
|
BOOST_TEST(BitVector[1000] == false);
|
|
BOOST_TEST(BitVector.isSmall());
|
|
BOOST_TEST(!BitVector.isZero());
|
|
|
|
BitVector.unset(0);
|
|
BOOST_TEST(BitVector.isZero());
|
|
BitVector.set(0);
|
|
|
|
// Test large
|
|
BitVector.set(FirstLargeBit);
|
|
BOOST_TEST(BitVector.requiredBits() == FirstLargeBit + 1);
|
|
BOOST_TEST(BitVector[0] == true);
|
|
BOOST_TEST(BitVector[1] == false);
|
|
BOOST_TEST(BitVector[1000] == false);
|
|
BOOST_TEST(BitVector[FirstLargeBit] == true);
|
|
BOOST_TEST(!BitVector.isSmall());
|
|
BOOST_TEST(!BitVector.isZero());
|
|
|
|
BitVector.unset(FirstLargeBit);
|
|
BOOST_TEST(BitVector[FirstLargeBit] == false);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestZero) {
|
|
LazySmallBitVector BitVector;
|
|
BitVector.set(0);
|
|
BitVector.set(1);
|
|
|
|
BitVector.zero(0, 1);
|
|
BOOST_TEST(BitVector[0] == false);
|
|
BOOST_TEST(!BitVector.isZero());
|
|
|
|
BitVector.zero();
|
|
BOOST_TEST(BitVector.isZero());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestEquality) {
|
|
LazySmallBitVector A;
|
|
LazySmallBitVector B;
|
|
|
|
// Test small
|
|
A.set(1);
|
|
BOOST_TEST(A != B);
|
|
B.set(1);
|
|
BOOST_REQUIRE_EQUAL(A, B);
|
|
|
|
// Test large
|
|
A.set(FirstLargeBit);
|
|
BOOST_TEST(A != B);
|
|
B.set(FirstLargeBit);
|
|
BOOST_REQUIRE_EQUAL(A, B);
|
|
|
|
// Test zero out
|
|
A.zero();
|
|
BOOST_TEST(A != B);
|
|
B.zero();
|
|
BOOST_REQUIRE_EQUAL(A, B);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestBitwiseOperators) {
|
|
// First loop iteration tests the small implementation, the second the large
|
|
// one
|
|
for (unsigned Start = 0; Start <= FirstLargeBit; Start += FirstLargeBit) {
|
|
LazySmallBitVector A;
|
|
LazySmallBitVector B;
|
|
|
|
// Test and
|
|
A.set(Start + 0);
|
|
B = A;
|
|
B.set(Start + 1);
|
|
|
|
A &= B;
|
|
BOOST_TEST(A.requiredBits() == Start + 1);
|
|
BOOST_TEST(A[Start + 0] == true);
|
|
|
|
A.zero();
|
|
B.zero();
|
|
|
|
A.set(Start + 0);
|
|
B = A;
|
|
B.set(Start + 1);
|
|
|
|
B &= A;
|
|
BOOST_REQUIRE_EQUAL(A, B);
|
|
|
|
A.zero();
|
|
B.zero();
|
|
|
|
// Test or
|
|
A.set(Start + 0);
|
|
B = A;
|
|
B.set(Start + 1);
|
|
|
|
A |= B;
|
|
BOOST_REQUIRE_EQUAL(A, B);
|
|
|
|
A.zero();
|
|
B.zero();
|
|
|
|
// Test xor
|
|
A.set(Start + 0);
|
|
B = A;
|
|
B.set(Start + 1);
|
|
B.set(Start + 2);
|
|
|
|
A ^= B;
|
|
BOOST_TEST(A[Start + 0] == false);
|
|
BOOST_TEST(A[Start + 1] == true);
|
|
BOOST_TEST(A[Start + 2] == true);
|
|
|
|
A.zero();
|
|
B.zero();
|
|
|
|
// Test shifts
|
|
A.set(Start + 0);
|
|
A <<= 1;
|
|
BOOST_TEST(A[Start + 0] == false);
|
|
BOOST_TEST(A[Start + 1] == true);
|
|
A >>= 1;
|
|
BOOST_TEST(A[Start + 0] == true);
|
|
BOOST_TEST(A[Start + 1] == false);
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestCopy) {
|
|
for (unsigned Start = 0; Start <= FirstLargeBit; Start += FirstLargeBit) {
|
|
LazySmallBitVector A;
|
|
A.set(Start + 1);
|
|
|
|
LazySmallBitVector B(A);
|
|
BOOST_TEST(B[Start + 1] == true);
|
|
|
|
LazySmallBitVector C = A;
|
|
BOOST_TEST(C[Start + 1] == true);
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestComparison) {
|
|
LazySmallBitVector A;
|
|
A.set(1);
|
|
BOOST_TEST(not(A < A));
|
|
|
|
LazySmallBitVector B;
|
|
BOOST_TEST(B < A);
|
|
|
|
B.set(2);
|
|
BOOST_TEST(A < B);
|
|
|
|
B.set(80);
|
|
BOOST_TEST(A < B);
|
|
BOOST_TEST(not(B < A));
|
|
|
|
A.set(160);
|
|
BOOST_TEST(B < A);
|
|
BOOST_TEST(not(A < B));
|
|
}
|
|
|
|
#include "boost/iterator/transform_iterator.hpp"
|
|
|
|
BOOST_AUTO_TEST_CASE(TestIterator) {
|
|
std::vector<unsigned> Results;
|
|
|
|
// Test small implementation
|
|
LazySmallBitVector A;
|
|
A.set(0);
|
|
A.set(16);
|
|
|
|
std::copy(A.begin(), A.end(), std::back_inserter(Results));
|
|
BOOST_REQUIRE_EQUAL(Results, (std::vector<unsigned>{ 0, 16 }));
|
|
Results.clear();
|
|
|
|
// Test empty
|
|
A.zero();
|
|
std::copy(A.begin(), A.end(), std::back_inserter(Results));
|
|
BOOST_TEST(Results.empty());
|
|
|
|
// Test large implementation
|
|
A.set(0);
|
|
A.set(1000);
|
|
A.set(16);
|
|
|
|
std::copy(A.begin(), A.end(), std::back_inserter(Results));
|
|
BOOST_REQUIRE_EQUAL(Results, (std::vector<unsigned>{ 0, 16, 1000 }));
|
|
}
|