00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _TemplateLibrary_BitField_H_
00019 #define _TemplateLibrary_BitField_H_ 1
00020
00029 #include <lib/sconfig.h>
00030
00031 #include <lib/salloc.h>
00032
00033
00043 template<typename T>inline uint CountBitsSet(T x)
00044 {
00045 uint sum=0;
00046 #if 0
00047
00048 while(x)
00049 { sum+=uint(x&T(1)); x>>=1; }
00050 #else
00051
00052 for(; x; sum++)
00053 { x &= x-T(1); }
00054 #endif
00055 return(sum);
00056 }
00057
00065 template<typename T>inline uint CountBitsCleared(T x)
00066 { return(uint(8*sizeof(T))-CountBitsSet(x)); }
00067
00068
00081 template<typename T>inline int SearchFirstSetBit(T x)
00082 {
00083 #if 1
00084 T tst=T(1);
00085 for(int s=0; s<int(8*sizeof(T)); tst<<=1,s++) if(x&tst) return(s);
00086 return(-1);
00087 #else
00088
00089
00090 return(x ? __builtin_ctz(x) : -1); DO NOT USE.
00091 #endif
00092 }
00093
00104 template<typename T>inline int SearchFirstClearedBit(T x)
00105 {
00106 T tst=T(1);
00107 for(int s=0; s<int(8*sizeof(T)); tst<<=1,s++) if(!(x&tst)) return(s);
00108 return(-1);
00109 }
00110
00111
00136 template<typename T,size_t N>class TLStaticBitField
00137 {
00138 friend int DoTestBitFields();
00139 public:
00142 typedef uint nents_t;
00143
00144 private:
00146 static const nents_t nents = (N+8*sizeof(T)-1)/(8*sizeof(T));
00148 static const T band = T(8*sizeof(T)-1);
00150 static const int bshift =
00151 sizeof(T)==1 ? 3 :
00152 sizeof(T)==2 ? 4 :
00153 sizeof(T)==4 ? 5 :
00154 sizeof(T)==8 ? 6 :
00155 sizeof(T)==16 ? 7 : 8;
00157 static const size_t bits_per_ent=8*sizeof(T);
00159
00160
00161
00162 static const T exmask = ( (N % (8*sizeof(T)))==0 ) ?
00163 T(0) : ~((T(1)<<(N % (8*sizeof(T))))-1);
00164
00166 static const T all_clr = T(0);
00168 static const T all_set = ~all_clr;
00169
00171 T bits[nents];
00172
00174 inline void _SetAllEnts(T val)
00175 { for(nents_t i=0; i<nents; i++) bits[i]=val; }
00177 inline void _CopyFrom(const TLStaticBitField<T,N> &b)
00178 { for(nents_t i=0; i<nents; i++) bits[i]=b.bits[i]; }
00179
00180 public:
00182 inline TLStaticBitField() {}
00184 inline TLStaticBitField(bool bitval)
00185 { _SetAllEnts(bitval ? all_set : all_clr); }
00187 inline TLStaticBitField(const TLStaticBitField<T,N> &b)
00188 { _CopyFrom(b); }
00190 inline ~TLStaticBitField() {}
00191
00193 inline TLStaticBitField &operator=(const TLStaticBitField<T,N> &b)
00194 { _CopyFrom(b); return(*this); }
00195
00197 inline void SetBit(size_t bit)
00198 { bits[bit>>bshift]|=T(1)<<(bit & band); }
00200 inline void ClrBit(size_t bit)
00201 { bits[bit>>bshift]&=~(T(1)<<(bit & band)); }
00203 inline bool GetBit(size_t bit)
00204 { return((bits[bit>>bshift]>>(bit & band))&T(1)); }
00206 inline void AssBit(size_t bit,bool val)
00207 { if(val) SetBit(bit); else ClrBit(bit); }
00208
00210 inline void SetAll()
00211 { _SetAllEnts(all_set); }
00213 inline void ClrAll()
00214 { _SetAllEnts(all_clr); }
00215
00217 inline size_t CountSet()
00218 {
00219 bits[nents-1]&=~exmask;
00220 size_t sum=0;
00221 for(nents_t i=0; i<nents; i++) sum+=CountBitsSet(bits[i]);
00222 return(sum);
00223 }
00224
00226 inline size_t CountClr()
00227 {
00228 bits[nents-1]|=exmask;
00229 size_t sum=0;
00230 for(nents_t i=0; i<nents; i++) sum+=CountBitsCleared(bits[i]);
00231 return(sum);
00232 }
00233
00239 inline ssize_t SearchFirstSet()
00240 {
00241 bits[nents-1]&=~exmask;
00242 for(nents_t i=0; i<nents; i++)
00243 if(bits[i]!=all_clr)
00244 return(SearchFirstSetBit(bits[i])+ssize_t(i*bits_per_ent));
00245 return(-1);
00246 }
00247
00253 inline ssize_t SearchFirstClr()
00254 {
00255 bits[nents-1]|=exmask;
00256 for(nents_t i=0; i<nents; i++)
00257 if(bits[i]!=all_set)
00258 return(SearchFirstClearedBit(bits[i])+
00259 ssize_t(i*bits_per_ent));
00260 return(-1);
00261 }
00262 };
00263
00264
00283 template<typename T>class TLDynamicBitField
00284 {
00285 friend int DoTestBitFields();
00286 public:
00289 typedef uint nents_t;
00290
00291 private:
00293 static const T band = T(8*sizeof(T)-1);
00295 static const int bshift =
00296 sizeof(T)==1 ? 3 :
00297 sizeof(T)==2 ? 4 :
00298 sizeof(T)==4 ? 5 :
00299 sizeof(T)==8 ? 6 :
00300 sizeof(T)==16 ? 7 : 8;
00302 static const size_t bits_per_ent=8*sizeof(T);
00303
00305 static const T all_clr = T(0);
00307 static const T all_set = ~all_clr;
00308
00310 size_t N;
00312 nents_t nents;
00314 T *bits;
00316
00317
00318
00319 T exmask;
00320
00322 inline void _SetAllEnts(T val)
00323 { for(nents_t i=0; i<nents; i++) bits[i]=val; }
00325 inline void _CopyFrom(const TLDynamicBitField<T> &b)
00326 {
00327 N=b.N; nents=b.nents; exmask=b.exmask; bits=ALLOC<T>(nents);
00328 for(nents_t i=0; i<nents; i++) bits[i]=b.bits[i];
00329 }
00331 static inline nents_t _NEntsOfN(size_t _N)
00332 { return( (_N+8*sizeof(T)-1)/(8*sizeof(T)) ); }
00334 inline void _SetVals(size_t _N)
00335 {
00336 N=_N; nents = _NEntsOfN(N);
00337 uint32 md = N % (8*sizeof(T));
00338 exmask = ( md==0 ) ? T(0) : ~((T(1)<<md)-1);
00339 }
00341 inline void _Initialize(size_t _N)
00342 { _SetVals(_N); bits=ALLOC<T>(nents); }
00344 inline void _Free()
00345 { bits=FREE(bits); N=0; nents=0; }
00346
00347 public:
00349 inline TLDynamicBitField(size_t _N) { _Initialize(_N); }
00352 inline TLDynamicBitField(size_t _N,bool bitval)
00353 { _Initialize(_N); _SetAllEnts(bitval ? all_set : all_clr); }
00355 inline TLDynamicBitField(const TLDynamicBitField<T> &b)
00356 { _CopyFrom(b); }
00358 inline ~TLDynamicBitField()
00359 { _Free(); }
00360
00362 inline TLDynamicBitField &operator=(const TLDynamicBitField<T> &b)
00363 { _Free(); _CopyFrom(b); return(*this); }
00364
00375 inline void resize(size_t newN)
00376 {
00377 if(_NEntsOfN(newN)!=nents)
00378 { _SetVals(newN); bits=REALLOC<T>(nents); }
00379 }
00380
00392 inline void resize(size_t newN,bool ini_val)
00393 {
00394 T val;
00395 if(ini_val) { val=all_set; bits[nents-1]|=exmask; }
00396 else { val=all_clr; bits[nents-1]&=~exmask; }
00397 nents_t old_nents=nents; resize(newN);
00398 for(; old_nents<nents; old_nents++) bits[old_nents]=val;
00399 }
00400
00402 inline void SetBit(size_t bit)
00403 { bits[bit>>bshift]|=T(1)<<(bit & band); }
00405 inline void ClrBit(size_t bit)
00406 { bits[bit>>bshift]&=~(T(1)<<(bit & band)); }
00408 inline bool GetBit(size_t bit)
00409 { return((bits[bit>>bshift]>>(bit & band))&T(1)); }
00411 inline void AssBit(size_t bit,bool val)
00412 { if(val) SetBit(bit); else ClrBit(bit); }
00413
00415 inline void SetAll()
00416 { _SetAllEnts(all_set); }
00418 inline void ClrAll()
00419 { _SetAllEnts(all_clr); }
00420
00422 inline size_t CountSet()
00423 {
00424 bits[nents-1]&=~exmask;
00425 size_t sum=0;
00426 for(nents_t i=0; i<nents; i++) sum+=CountBitsSet(bits[i]);
00427 return(sum);
00428 }
00429
00431 inline size_t CountClr()
00432 {
00433 bits[nents-1]|=exmask;
00434 size_t sum=0;
00435 for(nents_t i=0; i<nents; i++) sum+=CountBitsCleared(bits[i]);
00436 return(sum);
00437 }
00438
00444 inline ssize_t SearchFirstSet()
00445 {
00446 bits[nents-1]&=~exmask;
00447 for(nents_t i=0; i<nents; i++)
00448 if(bits[i]!=all_clr)
00449 return(SearchFirstSetBit(bits[i])+ssize_t(i*bits_per_ent));
00450 return(-1);
00451 }
00452
00458 inline ssize_t SearchFirstClr()
00459 {
00460 bits[nents-1]|=exmask;
00461 for(nents_t i=0; i<nents; i++)
00462 if(bits[i]!=all_set)
00463 return(SearchFirstClearedBit(bits[i])+
00464 ssize_t(i*bits_per_ent));
00465 return(-1);
00466 }
00467 };
00468
00471
00472 #endif