/*************************************************************************/ /* File : XBitArray.h */ /* Author : Aymeric Bard */ /* */ /* Virtools SDK */ /* Copyright (c) Virtools 2000, All Rights Reserved. */ /*************************************************************************/ #ifndef XBITARRAY_H #define XBITARRAY_H "$Id:$" #include "XArray.h" #include "VxMath.h" /************************************************ {filename:XBitArray} Summary: Set of bit flags. Remarks: o This class define a set of bit flags that may be treated as a virtual array but are stored in an efficient manner. o The class has methods to set, clear and return the i-th bit, resize the array, etc. ************************************************/ class XBitArray { public: XBitArray(int initialsize = 1) { if (initialsize<1) initialsize=1; m_Size = (initialsize<<5); if (m_Size > 32) { // we allocate only if > 32 m_Data = Allocate(initialsize); Clear(); } else { m_Flags = 0; } } ~XBitArray() { if (m_Size > 32) Free(); } // copy Ctor XBitArray(const XBitArray& a) { m_Size = a.m_Size; if (m_Size <= 32) m_Flags = a.m_Flags; else { m_Data = Allocate(m_Size>>5); memcpy(m_Data,a.m_Data,m_Size>>3); } } // operator = XBitArray& operator = (const XBitArray& a) { if (this != &a) { if (m_Size != a.m_Size) { if (m_Size > 32) Free(); m_Size = a.m_Size; if (m_Size > 32) { // we allocate only if > 32 m_Data = Allocate(m_Size>>5); memcpy(m_Data,a.m_Data,m_Size>>3); } else { m_Flags = a.m_Flags; } } else { if (m_Size>32) memcpy(m_Data,a.m_Data,m_Size>>3); else m_Flags = a.m_Flags; } } return *this; } // Reallocation if necessary void CheckSize(int n) { while (n >= m_Size) { // m_Size >= 32, always int size = (m_Size>>5); XDWORD* temp = Allocate(size+size); // Copy the old bits if (m_Size > 32) memcpy(temp,m_Data,size*sizeof(XDWORD)); else *temp = m_Flags; // Clear the new bits memset(temp+size,0,size*sizeof(XDWORD)); if (m_Size > 32) // we free only if we were allocated Free(); m_Data = temp; m_Size += m_Size; } } void CheckSameSize(XBitArray& a) { if (m_Size < a.m_Size) { if (a.m_Size > 32) { int size = a.m_Size>>5; int oldsize = m_Size>>5; XDWORD* temp = Allocate(size); // Copy the old bits if (m_Size > 32) memcpy(temp,m_Data,oldsize*sizeof(XDWORD)); else *temp = m_Flags; // Clear the new bits memset(temp+oldsize,0,(size-oldsize)*sizeof(XDWORD)); if (m_Size > 32) // we free only if we were allocated Free(); m_Data = temp; m_Size = a.m_Size; } } } // Summary: Returns if the n-th bit is set to 1 int IsSet(int n) { if (n >= m_Size) return 0; // Out of range if (m_Size <= 32) return (m_Flags & (1<>5] & (1<<(n&31))); // Allocated after the first DWORD } // Summary: Returns if the n-th bit is set to 1 int operator [] (int n) { return IsSet(n); } // Summary: Appends the bitcount first bits of integer v to the array void AppendBits(int n,int v,int bitcount) { int mask = 1; bitcount += n; for(int i=n;i>5] |= 1<<(n&31); } } else { // we have to reallocate CheckSize(n); m_Data[n>>5] |= 1<<(n&31); } } // Summary: Sets the n-th bit to 1 and return 0 if it was set, 1 otherwise int TestSet(int n) { if(n < m_Size) { if (m_Size <= 32) { // Only one dword long int mask = 1<>5; int mask = 1<<(n&31); if (m_Data[pos]&mask) return 0; m_Data[pos] |= mask; return 1; } } else { // we have to reallocate CheckSize(n); m_Data[n>>5] |= 1<<(n&31); return 1; } } // Summary: Sets the n-th bit to 0 void Unset(int n) { if(n < m_Size) { if (m_Size <= 32) { m_Flags &= ~(1<>5] &= ~(1<<(n&31)); } } } // Summary: Sets the n-th bit to 0 and return 1 if it was set, 0 otherwise int TestUnset(int n) { if(n < m_Size) { if (m_Size <= 32) { int mask = 1<>5; int mask = 1<<(n&31); if (m_Data[pos] & mask) { m_Data[pos] &= ~mask; return 1; } return 0; } } else return 0; } // Summary: Returns the number of bits int Size() const { return m_Size; } // Summary: Resets the array void Clear() { if (m_Size<=32) m_Flags = 0; else memset(m_Data,0,(m_Size>>3)); } // Summary: Sets all bits of the array to 1 // Warning : this functions sets all the allocated bits, not only the // used bits void Fill() { if (m_Size<=32) m_Flags = 0xffffffff; else memset(m_Data,0xff,(m_Size>>3)); } // Summary: Performs a binary AND with another array void And(XBitArray& a) { if (a.m_Size <= 32) { if (m_Size <= 32) m_Flags &= a.m_Flags; else { m_Data[0] &= a.m_Flags; // clear the remaining bytes int rsize = m_Size>>5; for (int i=1;i>5; int i = 0; for (;i>5; for (;i>5; int i = 0; for (;i>5; for (int i=0;i>5; for (int i=0;i>5; for (int i=0;i>5; for(int i=0;i>5; for (int i=0;i>5; for (int i=0;i>5; for (int i=0;i>5);i++) { for (int j=0;j<32;j++) { if (m_Data[i] & (1<>5)*sizeof(XDWORD)+(addstatic?sizeof(*this):0); } private: XDWORD* Allocate(int size) { return new XDWORD[size]; } void Free() { delete [] m_Data; } // the array itself {secret} // If the size is inferior strict to 32 // the data array is not allocated, we // just use the sapce of the pointer to store the // first bits union { XDWORD* m_Data; XDWORD m_Flags; }; // real size already allocated {secret} int m_Size; }; #endif // BITARRAY_H