home *** CD-ROM | disk | FTP | other *** search
- #ifndef WBitsIncluded
- #define WBitsIncluded
-
- // copyright (c) 1992, 1993 by Paul Wheaton
- // 1916 Brooks #205, Missoula, MT 59801
- //
- // voice phone: (406)543-7543
- // modem phone: (406)543-1144 (2400N81)
- // CompuServe: 72707,207
- // Internet: 72707.207@CompuServe.com
-
- #include <stdlib.h>
- #include <WStr.h>
- #include <WVec.h>
-
- // for access by BitVector only
- class BitRef
- {
- Byte huge* P; // pointer to byte containing bit
- Byte M; // mask for bit
- BitRef(Byte huge* BP, long BitOffset); // non-inlined due to 16M stuff
- friend BitVector;
- public:
- #ifdef BorlandFixedByteMath
- operator Bool() { return ((*P & M) != 0); }
- Bool operator=(Bool b)
- {
- if (b) *P |= M;
- else *P &= ~M;
- return b;
- }
- void operator&=(Bool b) { if (!b) *P &= ~M; }
- void operator|=(Bool b) { if (b) *P |= M; }
- void operator^=(Bool b) { if (b) *P ^= M; }
- #else
- operator Bool() { return ((int(*P) & int(M)) != 0); }
- Bool operator=(Bool b);
- void operator&=(Bool b);
- void operator|=(Bool b);
- void operator^=(Bool b);
- #endif
- #ifdef MAJORBBS
- void* operator new(size_t size){return malloc(size);}
- void operator delete(void* p) {free(p);}
- #endif
- };
-
- class BitVector : public ByteVector
- {
- long BitLen; // the number of bits used
- void CtorsHelper(const long* LP,long Length);
- public:
- // see the notes on the constructors at the end of this file
- BitVector();
- BitVector(long);
- BitVector(long,long);
- BitVector(long,long,long);
- BitVector(long,long,long,long);
- BitVector(long,long,long,long,long);
- BitVector(long,long,long,long,long,long);
- BitVector(long,long,long,long,long,long,long);
- BitVector(long,long,long,long,long,long,long,long);
- BitVector(long,long,long,long,long,long,long,long,long);
- BitVector(const Byte* B, long Len); // direct copy
- BitVector(const BitVector&);
- BitRef Ref(long Index);
- BitRef operator[](long Index);
- /* used for setting or retrieving bit elements. Accessing beyond the
- last bit will make this vector longer. */
- Bool operator()(long Index) const {return At(Index);}
- /* used for reading bits only. Accessing beyond the last bit will
- return a 0 (False). This is much faster than [] */
- Bool At(long Index) const;
- BitVector operator()(long Index,long Len) const {return At(Index,Len);}
- // for a subset
- BitVector At(long Index, long Len) const;
- BitVector Before(long Index) const {return At(0,Index);}
- BitVector Through(long Index) const {return At(0,Index+1);}
- BitVector From(long Index) const;
- BitVector After(long Index) const;
- void Toggle(long Index){Ref(Index)=!At(Index);}
- void operator=(const BitVector&);
- BitVector operator!() const;
- BitVector operator&(const BitVector&) const;
- BitVector operator^(const BitVector&) const;
- BitVector operator|(const BitVector&) const;
- void operator&=(const BitVector&);
- void operator^=(const BitVector&);
- void operator|=(const BitVector&);
- void ReAlloc(long NewCapacity);
- long Size() const {return BitLen;}
- long ByteSize() const {return Len;}
- void ClearRange(long Index1,long Index2);
- void SetRange(long Index1,long Index2,Bool X=On);
- operator String() const;
- };
-
- inline long BytesNeeded(long NumBits) {return(((NumBits-1)/8)+1);}
-
- /*
-
- BitVector constructors:
-
- I wanted to use a variable argument constructor (see your favorite texts
- on "elipsis", "...", "variable arguments" or "va_arg, va_end and
- va_start") but there were limitations that I felt could lead to very hard
- to find bugs, namely that the applications programmer must first pass a
- value that reveals how many parameters there are. Being off by one could
- lead to a variety of problems.
-
- There are four ways to construct a BitVector:
-
- 1) BitVector BV;
-
- This creates a vector that will have a length of 0 although some
- memory will be allocated so that elements may be added later (which
- is the most likely thing to happen).
-
- 2) BitVector BV(1,2,55,8);
-
- This creates a bit vector of length 56 (7 bytes long minimum). All
- of the bits are 0 (False) except for bits 1, 2, 55 and 8 which are 1
- (True). You may pass 1 to 9 parameters using this type of
- constructors. You're limited to 9 because the Glock C++ name
- mangling mixed with MSC 5.1 limits it this way (xxx). An update of
- either of these may solve this problem.
-
- 3) static Byte BA[]={1,2,55,8};
- BitVector BV(BA,4);
-
- This creates a vector of length 4, copying the elements from BA.
- You don't have to copy from an array of bytes, you can use any kind
- of array or even a pointer to anywhere in memory.
-
- 4) BitVector BV2(BV);
-
- Create a BitVector from another BitVector.
-
- */
- // for access by BitSets only
- class BitSetRef
- {
- Byte* P; // pointer to byte containing bit
- Byte M; // mask for bit
- public:
- BitSetRef(Byte* BP, int BitOffset);
- #ifdef BorlandFixedByteMath
- operator Bool() { return ((*P & M) != 0); }
- void operator&=(Bool b) { if (!b) *P &= ~M; }
- void operator|=(Bool b) { if (b) *P |= M; }
- void operator^=(Bool b) { if (b) *P ^= M; }
- #else
- operator Bool() { return ((int(*P) & int(M)) != 0); }
- void operator&=(Bool b);
- void operator|=(Bool b);
- void operator^=(Bool b);
- #endif
- Bool operator=(Bool b);
- #ifdef MAJORBBS
- void* operator new(size_t size){return malloc(size);}
- void operator delete(void* p) {free(p);}
- #endif
- };
-
- void ClearBitRange(void* P, long Index1,long Index2);
- void SetBitRange(void* P, long Index1,long Index2,Bool X=On);
- void QSB(Byte*P, int Index, Bool X=On); // Quick Set Bit for BitSet classes
-
- #define CreateBitSetClass(ClassName,BitQuan) \
- class ClassName \
- { \
- Byte B[(BitQuan+7)/8]; \
- public: \
- ClassName(){memset(&B[0],0,(BitQuan+7)/8);} \
- ClassName(const ClassName& BS){memcpy(&B[0],&(BS.B[0]),(BitQuan+7)/8);} \
- ClassName(int I){memset(&B[0],0,(BitQuan+7)/8); Ref(I)=On;} \
- ClassName(int I1, int I2){memset(&B[0],0,(BitQuan+7)/8); \
- Ref(I1)=On; Ref(I2)=On;} \
- ClassName(int I1, int I2, int I3){memset(&B[0],0,(BitQuan+7)/8); \
- QSB(B,I1); QSB(B,I2); QSB(B,I3);} \
- ClassName(int I1, int I2, int I3, int I4){memset(&B[0],0,(BitQuan+7)/8);\
- QSB(B,I1); QSB(B,I2); QSB(B,I3); QSB(B,I4);} \
- ClassName(int I1,int I2,int I3,int I4,int I5) \
- {memset(&B[0],0,(BitQuan+7)/8); QSB(B,I1); QSB(B,I2); QSB(B,I3); \
- QSB(B,I4); QSB(B,I5);} \
- ClassName(int I1,int I2,int I3,int I4,int I5,int I6) \
- {memset(&B[0],0,(BitQuan+7)/8); QSB(B,I1); QSB(B,I2); QSB(B,I3); \
- QSB(B,I4); QSB(B,I5); QSB(B,I6);} \
- ClassName(int I1,int I2,int I3,int I4,int I5,int I6,int I7) \
- {memset(&B[0],0,(BitQuan+7)/8); QSB(B,I1); QSB(B,I2); QSB(B,I3); \
- QSB(B,I4); QSB(B,I5); QSB(B,I6); QSB(B,I7);} \
- BitSetRef Ref(int Index) {return BitSetRef(&B[0],Index);} \
- BitSetRef operator[](int Index){return BitSetRef(&B[0],Index);} \
- Bool At(int Index){return ((B[Index/8] & (1<<(Index%8)) )!=0);} \
- Bool operator()(int Index) \
- {return ((B[Index/8] & (1<<(Index%8)) )!=0);} \
- void Toggle(int Index){Ref(Index)=!At(Index);} \
- void SetRange(int Index1, int Index2, Bool OnOrOff=On) \
- {SetBitRange(&B[0],Index1,Index2,OnOrOff);} \
- void ClearRange(int Index1, int Index2) \
- {ClearBitRange(&B[0],Index1,Index2);} \
- void SetAll(Bool OnOrOff=On) {SetBitRange(&B[0],0,BitQuan-1,OnOrOff);} \
- void ClearAll() {ClearBitRange(&B[0],0,BitQuan-1);} \
- long& L(){return *((long*)&B[0]);} \
- int& I(){return *((int*)&B[0]);} \
- char& C(){return *((char*)&B[0]);} \
- void* operator new(size_t size){return malloc(size);} \
- void operator delete(void* p) {free(p);} \
- };
-
- CreateBitSetClass(BitSet8,8);
- CreateBitSetClass(BitSet16,16);
- CreateBitSetClass(BitSet32,32);
-
- #define Bit0 1
- #define Bit1 2
- #define Bit2 4
- #define Bit3 8
- #define Bit4 16
- #define Bit5 32
- #define Bit6 64
- #define Bit7 128
- #define Bit8 256
- #define Bit9 512
- #define Bit10 1024
- #define Bit11 2048
- #define Bit12 4096
- #define Bit13 8192
- #define Bit14 16384
- #define Bit15 32768
- #define Bit16 65536
- #define Bit17 131072
- #define Bit18 262144
- #define Bit19 524288
- #define Bit20 1048576
- #define Bit21 2097152
- #define Bit22 4194304
- #define Bit23 8388608
- #define Bit24 16777216
- #define Bit25 33554432
- #define Bit26 67108864
- #define Bit27 134217728
- #define Bit28 268435456
- #define Bit29 536870912
- #define Bit30 1073741824
- #define Bit31 2147483648
-
- #endif