/* 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