Listing 4 Bitstring Class Definition and Inline Functions

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