源码如下。实现所有成员函数,实现了部分操作符重载。
#include <iostream>
using namespace std;
template <int COUNT_BITS>
class bitset
{
private:
unsigned char *data;
size_t cnt_bytes;
size_t cnt_bits;
static unsigned char mask[8];
// 将位偏移转化为字节偏移
int num_byte;
int bit_pos_in_byte;
void get_info(size_t pos)
{
num_byte = pos / 8;
bit_pos_in_byte = pos % 8;
}
void left_shift_one_bit()
{
bool left_carry = test(0);
data[0] >>= 1;
for (size_t i = 1; i < cnt_bytes; ++i)
{
if (test(i * 8))
{
set(i * 8 - 1);
}
else
{
set(i * 8 - 1, 0);
}
data[i] >>= 1;
}
if (left_carry)
{
set(COUNT_BITS - 1);
}
else
{
set(COUNT_BITS - 1, 0);
}
}
void right_shift_one_bit()
{
bool right_carry = test(COUNT_BITS - 1);
data[cnt_bytes - 1] <<= 1;
for (size_t i = 0; i < cnt_bytes - 1; ++i)
{
if (test(i * 8 + 7))
{
set(i * 8 + 8);
}
else
{
set(i * 8 + 8, 0);
}
data[i] <<= 1;
}
if (right_carry)
{
set(0);
}
else
{
set(0, 0);
}
}
public:
bitset()
{
cnt_bytes = COUNT_BITS / 8 + 1;
cnt_bits = COUNT_BITS % 8;
data = new unsigned char[cnt_bytes];
memset(data, 0, cnt_bytes);
}
~bitset()
{
delete data;
}
// test
bool test(size_t pos)
{
get_info(pos);
return (data[num_byte] & mask[bit_pos_in_byte]) == 0 ? false : true;
}
// set
bool set(size_t pos, int value = 1)
{
if (pos >= COUNT_BITS) return false;
get_info(pos);
if (value == 1)
{
data[num_byte] |= mask[bit_pos_in_byte];
}
else
{
data[num_byte] &= mask[bit_pos_in_byte] ^ 0xFF;
}
return true;
}
bool set()
{
for (size_t i = 0; i < cnt_bytes; ++i)
{
data[i] = 0xFF;
}
return true;
}
// flip
void flip()
{
for (size_t i = 0; i < cnt_bytes; ++i)
{
data[i] ^= 0xFF;// ~data[i];
}
}
// count
size_t count()
{
size_t cnt = 0;
for (int i = 0; i < COUNT_BITS; ++i)
{
if (test(i))
{
++cnt;
}
}
return cnt;
}
// any
bool any()
{
for (int i = 0; i < cnt_bytes - 1; ++i)
{
if (data[i] > 0) return true;
}
for (int i = 0; i < cnt_bits; ++i)
{
if (data[cnt_bytes - 1] & mask[i])
{
return true;
}
}
return false;
}
// none
bool none()
{
return !any();
}
// reset
void reset()
{
for (int i = 0; i < cnt_bytes; ++i)
{
data[i] = 0;
}
}
// size
size_t size()
{
return COUNT_BITS;
}
// to_string
string to_string()
{
string str(COUNT_BITS, '0');
for (size_t i = 0; i < COUNT_BITS; ++i)
{
if (test(i))
{
str[i] = '1';
}
}
return str;
}
// to_ulong
unsigned long to_ulong()
{
return *static_cast<unsigned long*>data;
}
// operator[]
int operator[](size_t pos)
{
return test(pos) ? 1 : 0;
}
// operator<<=
void operator<<=(size_t offset)
{
offset = offset % COUNT_BITS;
for (size_t i = 0; i < offset; ++i)
{
left_shift_one_bit();
}
}
void operator>>=(size_t offset)
{
offset = offset % COUNT_BITS;
for (size_t i = 0; i < offset; ++i)
{
right_shift_one_bit();
}
}
};
template <int COUNT_BITS>
unsigned char bitset<COUNT_BITS>::mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
void bitset_test()
{
bitset<11> bits;
bits.set(3);
for (size_t i = 0; i < 11; ++i)
{
if (bits.test(i))
{
cout << '1';
}
else
{
cout << '0';
}
}
cout << endl;
for (size_t i = 0; i < 11; ++i)
{
cout << bits[i];
}
cout << endl;
cout << bits.to_string().c_str() << endl;
bits.set();
cout << bits.to_string().c_str() << endl;
bits.set(3, 0);
cout << bits.to_string().c_str() << endl;
bits.flip();
cout << bits.to_string().c_str() << endl;
for (size_t i = 0; i < 20; ++i)
{
bits <<= i;
cout << bits.to_string().c_str() << endl;
bits >>= i;
}
}
int main()
{
bitset_test();
return 0;
}