// bitstr.h: The C++ bitstring class
#if !defined(BITSTR_H)
#define BITSTR_H
#include <stddef.h>
#include <limits.h>
#include <assert.h>
#include "string.hpp"
class istream;
class ostream;
class bitstring
{
public:
bitstring();
bitstring(unsigned long, size_t);
bitstring(const string&);
bitstring(const bitstring&);
~bitstring();
// Conversions
string to_string() const;
// Assignment
bitstring& operator=(const bitstring&);
// Equality
int operator==(const bitstring&) const;
int operator!=(const bitstring&) const;
// Basic bit operations
bitstring& set(size_t, int = 1);
bitstring& set();
bitstring& reset(size_t);
bitstring& reset();
bitstring& toggle(size_t);
bitstring& toggle();
int test(size_t) const;
int any() const;
int none() const;
bitstring operator~() const;
size_t count() const;
// Bitwise operators
bitstring& operator&=(const bitstring&);
bitstring& operator|(const bitstring&);
bitstring& operator^=(const bitstring&);
bitstring& operator>>=(size_t);
bitstring& operator<<=(size_t);
bitstring operator>>(size_t) const;
bitstring operator<<(size_t) const;
// String operations
bitstring& operator+=(const bitstring&);
bitstring& insert(size_t, const bitstring&);
bitstring& remove(size_t, size_t);
bitstring& replace(size_t, size_t, const bitstring&);
size_t find(int, size_t = 0) const;
size_t rfind(int, size_t = NPOS) const;
bitstring substr(size_t, size_t) const;
size_t length() const;
size_t length(size_t, int = 0);
size_t trim();
private:
typedef unsigned int Block;
Block *bits_;
size_t nbits_;
size_t nblks_;
Block clean_mask_;
enum {BLKSIZ = CHAR_BIT * sizeof(Block)};
static Block word(size_t b)
{return b / BLKSIZ;}
static Block offset(size_t b)
{return BLKSIZ - b%BLKSIZ - 1;}
static Block mask1(size_t b)
{return Block(1) << offset(b);}
static Block mask0(size_t b)
{return ~(Block(1) << offset(b));}
static size_t nblks(size_t nb)
{return (nb+BLKSIZ-1) / BLKSIZ;}
void make_clean_mask();
void cleanup();
void set_(size_t);
int set_(size_t, int);
void reset_(size_t);
int test_(size_t) const;
void from_string(const string&);
void init(size_t);
void equalize(bitstring&);
friend istream& operator>>(istream&, bitstring&);
};
// Global Functions:
ostream& operator<<(ostream&, const bitstring&);
istream& operator>>(istream&, bitstring&);
bitstring operator& (const bitstring&, const bitstring&);
bitstring operator|(const bitstring&, const bitstring&);
bitstring operator^ (const bitstring&, const bitstring&);
bitstring operator+ (const bitstring&, const bitstring&);
// Inline publics:
inline bitstring::bitstring()
{
init(0);
}
inline bitstring::~bitstring()
{
delete [] bits_;
}
inline bitstring& bitstring::toggle(size_t pos)
{
assert(pos < nbits_);
bits_[word(pos)] ^= mask1(pos);
return *this;
}
inline int bitstring::test(size_t pos) const
{
assert(pos < nbits_);
return test_(pos);
}
inline bitstring bitstring::operator~() const
{
bitstring b(*this);
b.toggle();
return b;
}
inline int bitstring::operator!=(const bitstring& b) const
{
return !operator==(b);
}
inline int bitstring::none() const
{
return !any();
}
inline size_t bitstring::length() const
{
return nbits_;
}
inline bitstring
operator&(const bitstring& x, const bitstring& y)
{
bitstring b(x);
return b &= y;
}
inline bitstring
operator|(const bitstring& x, const bitstring& y)
{
bitstring b(x);
return b |= y;
}
inline bitstring
operator^(const bitstring& x, const bitstring& y)
{
bitstring b(y);
return b ^= x;
}
inline bitstring bitstring::operator<<(size_t n) const
{
bitstring r(*this);
return r <<= n;
}
inline bitstring bitstring::operator>>(size_t n) const
{
bitstring r(*this);
return r >>= n;
}
inline bitstring
operator+(const bitstring& b1, const bitstring& b2)
{
bitstring b(b1);
return b.operator+=(b2);
}
// Inline privates:
inline void bitstring::make_cleanmask()
{
clean_mask = ~Block(0) << (nblks_ * BLKSIZ - nbits_);
}
inline void bitstring::cleanup()
{
// Make sure unused bits don't get set
if (nbits_ % BLKSIZ)
bits_[nblks_ - 1] &= clean_mask;
}
inline void bitstring::set_(size_t b)
{
bits_[word(b)] |= mask1(b);
}
inline void bitstring::reset_(size_t b)
{
bits_[word(b)] &= mask0(b);
}
inline int bitstring::test_(size_t b) const
{
return !!(bits_[word(b)] & maskl(b));
}
#endif
// End of File