/* bitvect.cppa8
Apr 19 2001
Chris Lacher
BitVector class implementation - array of unsigned char version
01/13/07: style upgrade
Copyright 2001 - 2007, R.C. Lacher
*/
#ifndef _BITVECT_CCP
#define _BITVECT_CCP
#include <iostream>
#include <stdlib.h>
#include <bitvect.h>
namespace fsu
{
std::ostream& operator << (std::ostream& os, const BitVector& bv)
// implementation by Spring 2004 Sec 51 and modified/simplified by Matt Porter
{
for (unsigned int i = 0; i < bv.Size(); ++i)
os << bv.Test(i);
return os;
}
//----------------------------------
// BitVector
//----------------------------------
// public methods
BitVector::BitVector (unsigned int numbits) // constructor
{
byteArraySize_ = (numbits + 7)/8;
byteArray_ = new unsigned char [byteArraySize_];
if (byteArray_ == 0)
{
std::cerr << "** BitVector memory allocation failure -- terminating program.\n";
exit (EXIT_FAILURE);
}
for (unsigned int i = 0; i < byteArraySize_; ++i)
byteArray_[i] = 0x00;
}
BitVector::BitVector (const BitVector& bv) // copy constructor
{
byteArraySize_ = bv.byteArraySize_;
byteArray_ = new unsigned char [byteArraySize_];
if (byteArray_ == 0)
{
std::cerr << "** BitVector memory allocation failure -- terminating program.\n";
exit (EXIT_FAILURE);
}
for (unsigned int i = 0; i < byteArraySize_; ++i)
byteArray_[i] = bv.byteArray_[i];
}
BitVector::~BitVector () // destructor
{
delete [] byteArray_;
}
BitVector& BitVector::operator = (const BitVector& bv)
// assignment operator
{
if (this != &bv)
{
if (byteArraySize_ != bv.byteArraySize_)
{
delete [] byteArray_;
byteArraySize_ = bv.byteArraySize_;
byteArray_ = new unsigned char [byteArraySize_];
if (byteArray_ == 0)
{
std::cerr << "** BitVector memory allocation failure -- terminating program.\n";
exit (EXIT_FAILURE);
}
}
for (unsigned int i = 0; i < byteArraySize_; ++i)
byteArray_[i] = bv.byteArray_[i];
}
return *this;
}
unsigned int BitVector::Size() const
// return size of bitvector
{
return 8 * byteArraySize_;
}
void BitVector::Set ()
// make all bits = 1
{
for (unsigned int i = 0; i < byteArraySize_; ++i)
byteArray_[i] = 0xFF;
}
void BitVector::Set (unsigned int index)
// make bit = 1: OR with mask
{
byteArray_[ByteNumber(index)] |= Mask(index);
}
void BitVector::Unset ()
// make all bits = 0
{
for (unsigned int i = 0; i < byteArraySize_; ++i)
byteArray_[i] = 0x00;
}
void BitVector::Unset (unsigned int index)
// make bit = 0: AND with inverted mask
{
byteArray_[ByteNumber(index)] &= ~ Mask(index);
}
void BitVector::Flip ()
// change all bit values
{
for (unsigned int i = 0; i < byteArraySize_; ++i)
byteArray_[i] ^= 0xFF;
}
void BitVector::Flip (unsigned int index)
// change bit value: XOR with mask
{
byteArray_[ByteNumber(index)] ^= Mask(index);
}
int BitVector::Test (unsigned int index) const
// return bit value
{
return 0 != (byteArray_[ByteNumber(index)] & Mask(index));
}
// private methods
size_t BitVector::ByteNumber (unsigned int index) const
{
// return index / 8
// shift right 3 is equivalent to, and faster than, dividing by 8
index = index >> 3;
if (index >= byteArraySize_)
{
std::cerr << "** BitVector error: index out of range\n";
exit (EXIT_FAILURE);
}
return index;
}
unsigned char BitVector::Mask (unsigned int index)
{
// return mask for index % 8
// the low order 3 bits is the remainder when dividing by 8
unsigned int shiftamount = index & 0x07; // low order 3 bits
return 0x01 << shiftamount;
}
} // namespace fsu
#endif