00001 #ifndef __UIUC_CS_CHARM_CKBITVECTOR_H 00002 #define __UIUC_CS_CHARM_CKBITVECTOR_H 00003 00004 #include "ckstream.h" 00005 00006 /* ************************************************************************ 00007 * 00008 * 0 indicates the least important bit of the bitvector 00009 * n indicates the most inportant bit of the bitvector 00010 * 00011 * the n'th bit sits at the highest bit of the first integer. 00012 * the 0'th bit sits at the lowest bit of the last integer. 00013 * 00014 * ************************************************************************ */ 00015 00016 typedef CmiUInt4 prio_t; 00017 00018 class CkBitVector { 00019 protected: 00020 prio_t usedBits; 00021 prio_t *data; 00022 00023 protected: 00024 static prio_t chunkBits() { return chunkSize()*8; } 00025 static prio_t chunkSize() { return sizeof(prio_t); } 00026 static prio_t chunks(prio_t n) { return (n + chunkBits()-1) / chunkBits(); } 00027 prio_t offset(prio_t bit) const { return chunks(usedBits-bit)-1; } 00028 prio_t mask(prio_t bit) const { 00029 unsigned int shift = (chunkBits()-(usedBits%chunkBits())+(bit%chunkBits())); 00030 shift %= chunkBits(); 00031 return (((prio_t)0x1)<<shift); 00032 } 00033 00034 public: 00035 static prio_t ilog2(prio_t val) { 00036 prio_t log = 0u; 00037 if ( val != 0u ) { 00038 while ( val > (1u<<log) ) { log++; } 00039 } 00040 return log; 00041 } 00042 00043 protected: 00044 void wipeData(); 00045 00046 public: 00047 int Length() const { return (int)usedBits; } 00048 00049 public: 00050 CkBitVector(); 00051 CkBitVector(const CkBitVector &b); 00052 CkBitVector(prio_t bits); 00053 CkBitVector(prio_t value, prio_t choices); 00054 00055 ~CkBitVector(); 00056 00057 CkBitVector & operator=(const CkBitVector &b); 00058 00059 // Bit operations. 0 is the least significant bit, and 32 (+) is the 00060 // most significant bit. 00061 CkBitVector & Zero(); 00062 CkBitVector & Invert(); 00063 CkBitVector & Clear(prio_t bit); 00064 CkBitVector & Set(prio_t bit); 00065 bool Test(prio_t bit) const; 00066 00067 // Shift down and shift up shift the bits in the bit vector by bit 00068 // bits around. The bits in the vector are moved up or down the 00069 // specified amount. The size of the bit vector does not change 00070 CkBitVector & ShiftDown(prio_t bits); 00071 CkBitVector & ShiftUp(prio_t bits); 00072 00073 // Change the size of the bit vector 00074 CkBitVector & Resize(prio_t bits); 00075 00076 // Union, Intersection, Difference 00077 CkBitVector & Union(CkBitVector const &b); 00078 CkBitVector & Intersection(CkBitVector const &b); 00079 CkBitVector & Difference(CkBitVector const &b); 00080 00081 // Concatenate two bit vectors together 00082 CkBitVector & Concat(CkBitVector const &b); 00083 00084 // Comparison operators 00085 int Compare(const CkBitVector &b) const; 00086 bool operator==(const CkBitVector &b) const { if(Compare(b) == 0) return true; else return false; } // HERE 00087 bool operator!=(const CkBitVector &b) const { return !(*this==b); } 00088 bool operator<(const CkBitVector &b) const { if(Compare(b) == -1) return true; else return false; } // HERE 00089 bool operator<=(const CkBitVector &b) const { return (*this==b||*this>b); } 00090 bool operator>(const CkBitVector &b) const { if(Compare(b) == 1) return true; else return false;} // HERE 00091 bool operator>=(const CkBitVector &b) const { return (*this==b||*this<b); } 00092 00093 // Print the bit vector to either output stream type 00094 friend CkOutStream & operator<< (CkOutStream &ckos, CkBitVector const b); 00095 friend CkErrStream & operator<< (CkErrStream &ckes, CkBitVector const b); 00096 00097 // And for charm 00098 void pup(PUP::er &p); 00099 00100 // For debugging in megatest 00101 #ifdef DEBUGGING 00102 CmiUInt4 * getData() { return data; } 00103 unsigned int getDataLength() { return chunks(usedBits); } 00104 #endif 00105 00106 friend class CkEntryOptions; 00107 }; 00108 00109 PUPmarshall(CkBitVector) 00110 00111 #endif /* __UIUC_CS_CHARM_CKBITVECTOR_H */