Skip to content
Permalink
51665236fa
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
390 lines (357 sloc) 15.6 KB
/*
* File: ds.DynamicBitset.test.h
* Author: saad
*
* Created on October 13, 2014, 1:29 AM
*/
#ifndef DS_DYNAMICBITSET_TEST_H
#define DS_DYNAMICBITSET_TEST_H
#if YASI_TEST_THIS_MODULE != 1
#define YASI_TEST_THIS_MODULE 1
#endif
#include "ds.DynamicBitset.h"
namespace yasi{
namespace ds{
////////////////// test ////////////////
class DynamicBitsetTest : public yasi::Test{
public:
void initSetGet(){
// test special cases
zeroBit();
oneBit();
fiveBits();
seventyBits();
}
void zeroBit(){
// setting/getting bits of a zero-bit key should fail
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(0); // should pass
key.setBit(0, 0); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(0); // should pass
key.getBit(0); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
// toString and toInt
DynamicBitset key(0); // should pass
ASSERT_EQ(std::string(""), key.toString()) << "toString() of zero-bit key not empty";
ASSERT_EQ(0, key.toInt()) << "toInt() of zero-bit key not zero";
}
void oneBit(){
DynamicBitset key(1); // 1 bit
int pos = 0;
ASSERT_EQ(1, key.numBytes);
ASSERT_EQ(1, key.numBits);
pos = 0;
key.setBit(pos, 1);
ASSERT_EQ(1, key.getBit(pos));
key.setBit(pos, 0);
ASSERT_EQ(0, key.getBit(pos));
// set/get out-of-bounds bit should fail
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(1);
key.setBit(2, 1); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(1);
key.setBit(-1, 1); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(1);
key.getBit(2); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(1);
key.getBit(-1); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
}
void fiveBits(){
DynamicBitset key(5); // 1 bit
int pos = 0;
ASSERT_EQ(1, key.numBytes);
ASSERT_EQ(5, key.numBits);
pos = 0;
key.setBit(pos, 1);
ASSERT_EQ(1, key.getBit(pos));
key.setBit(pos, 0);
ASSERT_EQ(0, key.getBit(pos));
pos = 3;
key.setBit(pos, 1);
ASSERT_EQ(1, key.getBit(pos));
key.setBit(pos, 0);
ASSERT_EQ(0, key.getBit(pos));
// set/get out-of-bounds bit should fail
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(5);
key.setBit(5, 1); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(5);
key.getBit(5); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
}
void seventyBits(){
const int nBits = 70;
int pos = 0;
DynamicBitset key(nBits); // 70 bits
ASSERT_EQ(9, key.numBytes);
ASSERT_EQ(nBits, key.numBits);
pos = 0;
key.setBit(pos, 1);
ASSERT_EQ(1, key.getBit(pos));
key.setBit(pos, 0);
ASSERT_EQ(0, key.getBit(pos));
pos = 13;
key.setBit(pos, 1);
ASSERT_EQ(1, key.getBit(pos));
key.setBit(pos, 0);
ASSERT_EQ(0, key.getBit(pos));
pos = 53;
key.setBit(pos, 1);
ASSERT_EQ(1, key.getBit(pos));
key.setBit(pos, 0);
ASSERT_EQ(0, key.getBit(pos));
// set/get out-of-bounds bit should fail
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(70);
key.setBit(70, 1); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
ASSERT_DEATH_IF_SUPPORTED({
DynamicBitset key(70);
key.getBit(70); // should fail
}, ".*" YASI_ASSERT_FAILED_STR ".*");
}
void setData(){
{
SCOPED_TRACE("setData() on 1 bit");
const int bits = 1;
// 1-bit key
DynamicBitset k(bits);
k.setData(1 << 31); // 10000000 00000000 00000000 00000000 should be ok
ASSERT_EQ(1, k.getBit(0));
DynamicBitset k2(bits);
k2.setData(7 << 29); // 11100000 00000000 00000000 00000000 using setData from constructor
ASSERT_EQ(1, k2.getBit(0));
ASSERT_EQ(k, k2); // == operator
DynamicBitset k3 = k2; // copy constructor
ASSERT_EQ(k3, k2);
k3.setData(0x80000000); // ignore lower-order bits, use only upper-order bits
k2.setData(0x70000000);
ASSERT_EQ(false, (k3 == k2)); // == operator
k3.setData(0x80000000); // ignore lower-order bits, use only upper-order bits
k2.setData(0xFFFFFFFF);
ASSERT_EQ(true, (k3 == k2)); // check only rightmost 1 bit
}
{
SCOPED_TRACE("setData() on 13 bits");
const int bits13 = 13;
// 13-bit key
DynamicBitset k(bits13);
k.setData(0x4CCFFFFF); // 01001100 11001111 11111111 11111111 should be ok
for (int i = 0; i < 13; i++){
if (i == 1 || i == 4 ||
i == 5 || i == 8 ||
i == 9 || i == 12){
ASSERT_EQ(1, k.getBit(i));
}
else{
ASSERT_EQ(0, k.getBit(i));
}
}
DynamicBitset k2(bits13);
k2.setData(0x4CCFFFFF); // 01001100 11001111 11111111 11111111 should be ok using setData from constructor
for (int i = 0; i < 13; i++){
if (i == 1 || i == 4 ||
i == 5 || i == 8 ||
i == 9 || i == 12){
ASSERT_EQ(1, k.getBit(i));
}
else{
ASSERT_EQ(0, k.getBit(i));
}
}
ASSERT_EQ(k, k2); // == operator
DynamicBitset k3 = k2; // copy constructor
ASSERT_EQ(k3, k2);
k3.setData(0x55580000);
k2.setData(0x54580000);
ASSERT_EQ(false, k3 == k2); // == operator
k3.setData(0x55580000);
k2.setData(0x555FFFFF);
ASSERT_EQ(true, k3 == k2); // check only rightmost 13 bits
}
}
void toInt(){
{
SCOPED_TRACE("1-bit");
const int bits = 1;
DynamicBitset k(bits);
k.setData(0x80000000); // 1
ASSERT_EQ(0x80000000, k.toInt());
k.setData(0x00000000);
ASSERT_EQ(0, k.toInt());
}
{
SCOPED_TRACE("5-bits");
const int bits = 5;
int value = 0xC8FFFFFF; // 11001000 11111111 11111111 11111111
DynamicBitset k(bits);
k.setData(value);
ASSERT_EQ(0xC8000000, k.toInt()); // 11001000 00000000 00000000 00000000
value = 0x50AAAAAA; // 01010000 10101010 10101010 10101010
DynamicBitset k2(bits);
k2.setData(value);
ASSERT_EQ(0x50000000, k2.toInt());
}
{
SCOPED_TRACE("13-bits");
const int bits = 13;
int value = 0x519FAAAA; // 01010001 10011111 10101010 10101010
DynamicBitset k(bits);
k.setData(value);
ASSERT_EQ(0x51980000, k.toInt());
}
{
SCOPED_TRACE("32-bits");
const int bits = 32;
int value = 0x5198ABCD;
DynamicBitset k(bits);
k.setData(value);
ASSERT_EQ(0x5198ABCD, k.toInt());
}
}
void toString(){
{
SCOPED_TRACE("32-bits");
const int bits = 32;
int value = 0x5198AAAA;
DynamicBitset k(bits);
k.setData(value);
ASSERT_EQ("01010001100110001010101010101010", k.toString());
}
{
SCOPED_TRACE("13-bits");
const int bits = 13;
int value = 0x5198AAAA;
DynamicBitset k(bits);
k.setData(value);
ASSERT_EQ("0101000110011", k.toString());
}
{
SCOPED_TRACE("1-bit");
const int bits = 1;
int value = 0x5198AAAA;
DynamicBitset k(bits);
k.setData(value);
ASSERT_EQ("0", k.toString());
k.setData(0x80000000);
ASSERT_EQ("1", k.toString());
}
}
void anyAllFlipReset(){
{
// zero bits
DynamicBitset b(0);
ASSERT_EQ(false, b.any());
ASSERT_EQ(false, b.all());
}
{
SCOPED_TRACE("Less than 8 bits");
DynamicBitset b(5); // all zero bits
ASSERT_EQ(false, b.any());
ASSERT_EQ(false, b.all());
int tweakIndex = 3;
b.setBit(tweakIndex, 1);
ASSERT_EQ(std::string("00010"), b.toString()) << "bitset bad";
ASSERT_EQ(true, b.any());
ASSERT_EQ(false, b.all());
b.flip(); // all ones except bit at tweakIndex
ASSERT_EQ(std::string("11101"), b.toString()) << "bitset bad";
ASSERT_EQ(false, b.getBit(tweakIndex));
for(int i = 0; i < b.numBits; i++){
if(i == tweakIndex)
ASSERT_EQ(false, b.getBit(i));
else
ASSERT_EQ(true, b.getBit(i));
}
b.flipBit(tweakIndex);
ASSERT_EQ(std::string("11111"), b.toString()) << "bitset bad";
ASSERT_EQ(true, b.any());
ASSERT_EQ(true, b.all());
}
{
SCOPED_TRACE("Exactly 8 bits");
DynamicBitset b(8); // all zero bits
ASSERT_EQ(false, b.any());
ASSERT_EQ(false, b.all());
int tweakIndex = 7;
b.setBit(tweakIndex, 1);
ASSERT_EQ(std::string("00000001"), b.toString()) << "bitset bad";
ASSERT_EQ(true, b.any());
ASSERT_EQ(false, b.all());
b.flip(); // all ones except bit at tweakIndex
ASSERT_EQ(std::string("11111110"), b.toString()) << "bitset bad";
ASSERT_EQ(false, b.getBit(tweakIndex));
for(int i = 0; i < b.numBits; i++){
if(i == tweakIndex)
ASSERT_EQ(false, b.getBit(i));
else
ASSERT_EQ(true, b.getBit(i));
}
b.flipBit(tweakIndex);
ASSERT_EQ(std::string("11111111"), b.toString()) << "bitset bad";
ASSERT_EQ(true, b.any());
ASSERT_EQ(true, b.all());
}
{
SCOPED_TRACE("37 bits");
DynamicBitset b(37); // all zero bits
ASSERT_EQ(false, b.any());
ASSERT_EQ(false, b.all());
// tweak a bit in a non-last byte
int tweakIndex = 3;
b.setBit(tweakIndex, 1);
ASSERT_EQ(true, b.any());
ASSERT_EQ(false, b.all());
b.flip(); // all ones except bit at tweakIndex
ASSERT_EQ(false, b.getBit(tweakIndex));
for(int i = 0; i < b.numBits; i++){
if(i == tweakIndex)
ASSERT_EQ(false, b.getBit(i));
else
ASSERT_EQ(true, b.getBit(i));
}
b.flipBit(tweakIndex);
ASSERT_EQ(true, b.any());
ASSERT_EQ(true, b.all());
// tweak a bit in the last byte
b.reset(); // all zero again
ASSERT_EQ(false, b.any());
ASSERT_EQ(false, b.all());
// tweak a bit in a non-last byte
tweakIndex = 34;
b.setBit(tweakIndex, 1);
ASSERT_EQ(true, b.any());
ASSERT_EQ(false, b.all());
b.flip(); // all ones except bit at tweakIndex
ASSERT_EQ(false, b.getBit(tweakIndex));
for(int i = 0; i < b.numBits; i++){
if(i == tweakIndex)
ASSERT_EQ(false, b.getBit(i));
else
ASSERT_EQ(true, b.getBit(i));
}
b.flipBit(tweakIndex);
ASSERT_EQ(true, b.any());
ASSERT_EQ(true, b.all());
}
}
};
ADD_TEST_F(DynamicBitsetTest, initSetGet);
ADD_TEST_F(DynamicBitsetTest, setData);
ADD_TEST_F(DynamicBitsetTest, toInt);
ADD_TEST_F(DynamicBitsetTest, toString);
ADD_TEST_F(DynamicBitsetTest, anyAllFlipReset);
}
}
#endif /* DS_DYNAMICBITSET_TEST_H */