home *** CD-ROM | disk | FTP | other *** search
- #include <mem.h>
- #include <dos.h>
- #include <assert.h>
-
- #include "bitset.h"
-
- inline int set_size(int low, int high)
- {
- if (low >= high) return 0;
- return ((((high - low + 1) >> 3) + 3) & 0xFFF0) + 12;
- }
-
- bitset::bitset()
- {
- low = 0;
- siz = 0;
- high = -1;
- data = NULL;
- }
-
- void bitset::expand(int new_low, int new_high)
- {
- int new_size;
- char *new_data;
-
- new_low &= 0xFFF8;
- if (data == NULL) {
- low = new_low;
- high = low - 1;
- }
- if (new_low > low)
- new_low = low;
- if ((new_high = ((new_high & 0xFFF8) + 7)) < high)
- new_high = high;
- if (new_low < low || new_high > high) {
- new_size = set_size(new_low, new_high);
- if (new_size > siz) {
- new_data = new char[new_size];
- assert(FP_SEG(new_data) < 0xA000);
- memcpy(new_data, data, siz);
- if (data != NULL)
- delete data;
- data = new_data;
- siz = new_size;
- }
- assert(siz > 0);
- if (low > new_low) {
- int o = (low - new_low) >> 3;
- assert(siz >= o + ((high - low + 1) >> 3));
- memmove(data + o, data, (high - low + 1) >> 3);
- assert(siz >= o);
- memset(data, 0, o);
- low = new_low;
- }
- if (high < new_high) {
- assert(siz >= ((high - low + 1) >> 3) + ((new_high - high) >> 3));
- memset(data + ((high - low + 1) >> 3), 0, ((new_high - high) >> 3));
- high = new_high;
- }
- assert(FP_SEG(data) < 0xA000);
- }
- }
-
- void bitset::contract()
- {
- char *pt;
- int new_low;
- int new_high;
- int new_size;
- int o;
- int s;
-
- if (data == NULL) return;
- new_low = low;
- new_high = high;
- pt = data;
- while ((new_low < high) && !*pt++)
- new_low += 8;
- pt = data + ((high - low - 7) >> 3);
- while ((new_high > new_low) && !*pt--)
- new_high -= 8;
- if (new_high <= new_low) {
- low = 0;
- high = -1;
- delete data;
- data = NULL;
- siz = 0;
- } else if (new_low > low || new_high < high) {
- new_size = set_size(new_low, new_high);
- s = (new_high - new_low + 1) >> 3;
- assert(new_size > 0);
- o = (new_low - low) >> 3;
- if (new_size < siz) {
- pt = new char [new_size];
- assert(new_size >= s);
- memcpy(pt, data + o, s);
- delete data;
- data = pt;
- siz = new_size;
- } else if (low < new_low) {
- assert(siz > s);
- memmove(data, data + o, s);
- }
- low = new_low;
- high = new_high;
- }
- }
-
- bitset::~bitset()
- {
- if (data != NULL) {
- assert(FP_SEG(data) > 10);
- if (FP_SEG(data) >= 0xA000)
- assert(FP_SEG(data) < 0xA000);
- delete data;
- data = NULL;
- siz = 0;
- }
- }
-
- bitset::bitset(int n)
- {
- low = n & 0xFFF8;
- high = low + 7;
- siz = set_size(low, high);
- data = new char[siz];
- *data = 1 << (n - low);
- }
-
- bitset::bitset(int start, int stop)
- {
- low = 0;
- high = -1;
- data = NULL;
- siz = 0;
- set(start, stop);
- }
-
- bitset::bitset(bitset& arg)
- {
- low = arg.low;
- high = arg.high;
- siz = arg.siz;
- if (arg.data == NULL)
- data = NULL;
- else {
- data = new char[siz];
- memcpy(data, arg.data, siz);
- }
- }
-
- int bitset::max()
- {
- int i, n;
-
- contract();
- if (data == NULL) return 0;
- n = data[(high - low) >> 3];
- i = high - 7;
- while ((n >>= 1) && i++) ;
- return i;
- }
-
- int bitset::min()
- {
- int i;
-
- contract();
- if (data == NULL) return 0;
- i = 0;
- while (!((1 << i) & *data)) i++;
- return low + i;
- }
-
- void bitset::set(int start, int stop)
- {
- int size;
-
- if (start > stop) return;
- expand(start, stop);
- assert(FP_SEG(data) < 0xA000);
- start -= low;
- stop -= low;
- size = (stop >> 3) - (start >> 3) - 1;
- assert(start >= 0);
- if (size < 0) {
- assert(siz > (start >> 3));
- data[start >> 3] |=
- (0xFF << (start & 7)) & (0xFF >> (7 - (stop & 7)));
- } else {
- if (size > 0) {
- assert(siz >= (start >> 3) + size + 1);
- memset(data + (start >> 3) + 1, 0xFF, size);
- }
- assert(siz > (start >> 3));
- data[start >> 3] |= 0xFF << (start & 7);
- assert(siz > (stop >> 3));
- data[stop >> 3] |= 0xFF >> (7 - (stop & 7));
- }
- assert(FP_SEG(data) < 0xA000);
- }
-
- void bitset::clear()
- {
- if (data != NULL)
- delete data;
- data = NULL;
- high = -1;
- low = 0;
- siz = 0;
- }
-
- void bitset::clear(int start, int stop)
- {
- int size;
-
- if (start > stop) return;
- if (data == NULL) return;
- if (stop > high)
- stop = high;
- if (start < low)
- start = low;
- start -= low;
- stop -= low;
- assert(start >= 0);
- size = (stop >> 3) - (start >> 3) - 1;
- if (size < 0) {
- assert(siz > (start >> 3));
- data[start >> 3] &=
- (0xFF >> (8 - (start & 7))) & (0xFF << ((stop & 7) + 1));
- } else {
- if (size > 0) {
- assert(siz >= (start >> 3) + size + 1);
- memset(data + (start >> 3) + 1, 0, size);
- }
- assert(siz > (start >> 3));
- data[start >> 3] &= 0xFF >> (8 - (start & 7));
- assert(siz > (stop >> 3));
- data[stop >> 3] &= 0xFF << ((stop & 7) + 1);
- }
- contract();
- }
-
- unsigned bitset::size()
- {
- unsigned count = 0;
- unsigned i, j;
- unsigned n;
- char bit;
- char *pt;
-
- pt = data;
- n = (high - low + 1) >> 3;
- while (n--) {
- bit = 1;
- j = 8;
- while (j--) {
- if ((*pt & bit) != 0)
- count++;
- bit <<= 1;
- }
- pt++;
- }
- return count;
- }
-
- char bitset::operator [] (int i)
- {
- if (i < low || i > high)
- return 0;
- return data[(i - low) >> 3] & 1 << ((i - low) & 7);
- }
-
- int bitset::operator == (bitset& arg)
- {
- char *pt1, *pt2;
- int size;
-
- contract();
- arg.contract();
- if (data == NULL && arg.data == NULL)
- return 1;
- if (high != arg.high || low != arg.low)
- return 0;
- size = (high - low + 1) >> 3;
- pt1 = data;
- pt2 = arg.data;
- while (size--)
- if (*pt1++ != *pt2++)
- return 0;
- return 1;
- }
-
- int bitset::operator != (bitset& arg)
- {
- return !(*this == arg);
- }
-
- int bitset::operator > (bitset& arg)
- {
- char *pt1;
- char *pt2;
- int size;
-
- arg.contract();
- if (arg.data == NULL)
- return 1;
- if (arg.low < low || arg.high > high)
- return 0;
- pt1 = data + ((arg.low - low) >> 3);
- pt2 = arg.data;
- size = (arg.high - arg.low) >> 3;
- while (size--)
- if ((*pt1++ ^ 0xFF) & *pt2++)
- return 0;
- return 1;
- }
-
- int bitset::operator < (bitset& arg)
- {
- return arg > *this;
- }
-
- bitset::operator void * ()
- {
- char *pt;
- int size;
-
- if (data == NULL)
- return NULL;
- pt = data;
- size = (high - low + 1) >> 3;
- while (size--)
- if (*pt++)
- return (void *) -1;
- return NULL;
- }
-
- int bitset::operator ! ()
- {
- return ((void *) *this) == NULL;
- }
-
- bitset bitset::operator + (int i)
- {
- bitset temp(*this);
- return temp += i;
- }
-
- bitset bitset::operator - (int i)
- {
- bitset temp(*this);
- return temp -= i;
- }
-
- bitset bitset::operator + (bitset& arg)
- {
- bitset temp(*this);
- return temp += arg;
- }
-
- bitset bitset::operator - (bitset& arg)
- {
- bitset temp(*this);
- return temp -= arg;
- }
-
- bitset bitset::operator * (bitset& arg)
- {
- bitset temp(*this);
- return temp *= arg;
- }
-
- bitset& bitset::operator = (bitset& arg)
- {
- int size;
-
- clear();
- high = arg.high;
- low = arg.low;
- siz = arg.siz;
- if (arg.data == NULL)
- data = NULL;
- else {
- data = new char[siz];
- memcpy(data, arg.data, siz);
- }
- return *this;
- }
-
- bitset& bitset::operator += (int i)
- {
- set(i, i);
- return *this;
- }
-
- bitset& bitset::operator -= (int i)
- {
- clear(i,i);
- return *this;
- }
-
- bitset& bitset::operator += (bitset& arg)
- {
- char *source;
- char *dest;
- int size;
-
- expand(arg.low, arg.high);
- source = arg.data;
- dest = data + ((arg.low - low) >> 3);
- size = (arg.high - arg.low + 1) >> 3;
- assert(arg.low >= low);
- assert(siz >= size + ((arg.low - low) >> 3));
- while (size--)
- *dest++ |= *source++;
- return *this;
- }
-
- bitset &bitset::operator -= (bitset& arg)
- {
- int start;
- int stop;
- int size;
- char *dest;
- char *source;
-
- if ((start = low) < arg.low)
- start = arg.low;
- if ((stop = high) > arg.high)
- stop = arg.high;
- if (start <= stop) {
- dest = data + ((start - low) >> 3);
- source = arg.data + ((start - arg.low) >> 3);
- size = (stop - start + 1) >> 3;
- assert(arg.siz >= size + ((start - arg.low) >> 3));
- assert(siz >= size + ((start - low) >> 3));
- while (size--)
- *dest++ &= 0xFF ^ *source++;
- }
- contract();
- return *this;
- }
-
- bitset &bitset::operator *= (bitset& arg)
- {
- int start;
- int stop;
- int size;
- char *source;
- char *dest;
-
- if (low < arg.low)
- clear(low, arg.low - 1);
- if (high > arg.high)
- clear(arg.high + 1, high);
- if ((start = low) < arg.low)
- start = arg.low;
- if ((stop = high) > arg.high)
- stop = arg.high;
- if (start <= stop) {
- if (low > start)
- assert(start >= low);
- dest = data + ((start - low) >> 3);
- assert(start >= arg.low);
- source = arg.data + ((start - arg.low) >> 3);
- size = (stop - start + 1) >> 3;
- assert(arg.siz >= size + ((start - arg.low) >> 3));
- assert(siz >= size + ((start - low) >> 3));
- while (size--)
- *dest++ &= *source++;
- }
- assert(FP_SEG(data) < 0xA000);
- contract();
- assert(FP_SEG(data) < 0xA000);
- return *this;
- }
-
-