00001 #ifndef _BitSet_h_
00002 #define _BitSet_h_
00003
00004 #include <Base.h>
00005
00006 template <class T=uint32_t>
00007 class BitSet {
00008 private:
00009 const static uint8_t DivideLog = 3;
00010 const static uint32_t ModMask = ~((uint32_t)0xffffffff << DivideLog);
00011
00012 uint32_t maximum;
00013 uint8_t* bits;
00014 uint32_t cardinality;
00015 T* elements;
00016
00017 uint32_t internalCount(){
00018 return (maximum >> DivideLog) + (maximum & ModMask ? 1 : 0);
00019 }
00020
00021 public:
00022 BitSet(uint32_t maxVal,T* arr=NULL) : maximum(maxVal),cardinality(0),elements(arr) {
00023 uint32_t count = internalCount();
00024 bits = new uint8_t[count];
00025 bzero(bits,count);
00026 }
00027
00029 BitSet(BitSet& src){
00030 maximum = src.maximum;
00031 uint32_t count = src.internalCount();
00032 bits = new uint8_t[count];
00033 memcpy(bits,src.bits,count);
00034 cardinality = src.cardinality;
00035 elements = src.elements;
00036 }
00037
00038 ~BitSet() { delete[] bits; }
00039
00040 BitSet& operator&=(BitSet& src){
00041 ASSERT((maximum == src.maximum) && "FATAL: Two sets with different max numbers are ANDed");
00042
00043 uint32_t count = internalCount();
00044 for(uint32_t i=0;i<count;i++){
00045 bits[i] &= src.bits[i];
00046 }
00047 cardinality = 0;
00048 for(uint32_t i=0;i<maximum;i++){
00049 if(contains(i)){
00050 cardinality++;
00051 }
00052 }
00053 return *this;
00054 }
00055 BitSet& operator|=(BitSet& src){
00056
00057 ASSERT((maximum == src.maximum) && "FATAL: Two sets with different max numbers are ORed");
00058
00059 uint32_t count = internalCount();
00060 for(uint32_t i=0;i<count;i++){
00061 bits[i] |= src.bits[i];
00062 }
00063 cardinality = 0;
00064 for(uint32_t i=0;i<maximum;i++){
00065 if(contains(i)){
00066 cardinality++;
00067 }
00068 }
00069 return *this;
00070 }
00071
00073
00077 BitSet& operator~(){
00078 uint32_t count = internalCount();
00079 for (uint32_t i = 0; i < count; i++){
00080 bits[i] = ~bits[i];
00081 }
00082 cardinality = maximum-cardinality;
00083 return *this;
00084 }
00085
00086 inline void clear() {
00087 uint32_t count = internalCount();
00088 bzero(bits,count);
00089 cardinality = 0;
00090 }
00091
00092 inline void setall() {
00093 uint32_t count = internalCount();
00094 memset(bits,0xff,count);
00095 cardinality = maximum;
00096 }
00097 void print() {
00098 uint32_t count = internalCount();
00099 fprintf(stdout, "%d bits: ", maximum);
00100 for (uint32_t i = 0; i < count; i++){
00101 fprintf(stdout, "%2x", bits[i]);
00102 }
00103 fprintf(stdout, "\n");
00104 }
00105
00106 inline void insert(uint32_t n){
00107 if(n >= maximum)
00108 return;
00109 uint32_t index = n >> DivideLog;
00110 uint8_t mask = 1 << (n & ModMask);
00111 if(!(bits[index] & mask))
00112 cardinality++;
00113 bits[index] |= mask;
00114 }
00115
00116 inline void remove(uint32_t n){
00117 if(n >= maximum)
00118 return;
00119 uint32_t index = n >> DivideLog;
00120 uint8_t mask = 1 << (n & ModMask);
00121 if(bits[index] & mask)
00122 cardinality--;
00123 bits[index] &= ~mask;
00124 }
00125
00126 inline bool contains(uint32_t n){
00127 if(n >= maximum)
00128 return false;
00129 uint32_t index = n >> DivideLog;
00130 uint8_t mask = 1 << (n & ModMask);
00131 return (bits[index] & mask);
00132 }
00133
00134 inline uint32_t size() { return cardinality; }
00135 inline bool empty() { return !cardinality; }
00136
00138
00139
00140
00141
00142 T* duplicateMembers(){
00143 if(!size())
00144 return NULL;
00145
00146 T* ret = new T[size()];
00147
00148 uint32_t arrIdx = 0;
00149 uint32_t idx = 0;
00150 for(uint32_t i=0;idx<maximum;i++){
00151 uint8_t value = bits[i];
00152 for(uint32_t j=0;(j<(1 << DivideLog)) && (idx<maximum);j++,idx++){
00153 uint8_t mask = 1 << j;
00154 if(value & mask)
00155 ret[arrIdx++] = elements[idx];
00156 }
00157 }
00158
00159 ASSERT(size() == arrIdx);
00160
00161 return ret;
00162 }
00163 };
00164
00165 #endif