Phoenix
Object-oriented orthogonally persistent operating system
BitString.h
Go to the documentation of this file.
00001 /*
00002  * /phoenix/include/BitString.h
00003  *
00004  * This file is a part of Phoenix operating system.
00005  * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com>
00006  * All rights reserved.
00007  * See COPYING file for copyright details.
00008  */
00009 
00010 #ifndef BITSTRING_H_
00011 #define BITSTRING_H_
00012 
00030 template <size_t numBits = 0>
00031 class BitString {
00032 public:
00033     inline BitString() {
00034         memset(_bits, 0, sizeof(_bits));
00035     }
00036 
00041     inline void Set(size_t idx) {
00042         ASSERT(idx < numBits);
00043         _bits[idx / NBBY] |= 1 << (idx % NBBY);
00044     }
00045 
00050     inline void Clear(size_t idx) {
00051         ASSERT(idx < numBits);
00052         _bits[idx / NBBY] &= ~(1 << (idx % NBBY));
00053     }
00054 
00060     inline bool IsSet(size_t idx) {
00061         ASSERT(idx < numBits);
00062         return _bits[idx / NBBY] & (1 << (idx % NBBY));
00063     }
00064 
00070     inline bool IsClear(size_t idx) {
00071         ASSERT(idx < numBits);
00072         return !IsSet(idx);
00073     }
00074 
00081     inline bool operator[](size_t idx) {
00082         return IsSet(idx);
00083     }
00084 
00089     int FirstSet() {
00090         const size_t numWords = numBits / (sizeof(uintptr_t) * NBBY);
00091         for (size_t word = 0; word < numWords; word++) {
00092             uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word];
00093             if (x) {
00094                 size_t bit = cpu::bsf(x);
00095                 bit += word * sizeof(uintptr_t) * NBBY;
00096                 return bit;
00097             }
00098         }
00099         /* Check remainder. */
00100         for (size_t idx = numWords * sizeof(uintptr_t) * NBBY;
00101              idx < numBits;
00102              idx++) {
00103 
00104             if (IsSet(idx)) {
00105                 return idx;
00106             }
00107         }
00108         return -1;
00109     }
00110 
00115     int FirstClear() {
00116         const size_t numWords = numBits / (sizeof(uintptr_t) * NBBY);
00117         for (size_t word = 0; word < numWords; word++) {
00118             uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word];
00119             if (x != static_cast<uintptr_t>(~0)) {
00120                 size_t bit = cpu::bsf(~x);
00121                 bit += word * sizeof(uintptr_t) * NBBY;
00122                 return bit;
00123             }
00124         }
00125         /* Check remainder. */
00126         for (size_t idx = numWords * sizeof(uintptr_t) * NBBY;
00127              idx < numBits;
00128              idx++) {
00129 
00130             if (IsClear(idx)) {
00131                 return idx;
00132             }
00133         }
00134         return -1;
00135     }
00136 
00138     inline void ClearAll() {
00139         memset(_bits, 0, sizeof(_bits));
00140     }
00141 
00142     inline void SetAll() {
00143         memset(_bits, 0xff, sizeof(_bits));
00144     }
00145 
00146     inline void Invert() {
00147         const size_t numWords = numBits / (sizeof(uintptr_t) * NBBY);
00148         for (size_t word = 0; word < numWords; word++) {
00149             static_cast<uintptr_t *>(static_cast<void *>(_bits))[word] ^= ~0ul;
00150         }
00151         /* Invert remainder. */
00152         for (size_t idx = numWords * sizeof(uintptr_t);
00153              idx < (numBits + NBBY - 1) / NBBY;
00154              idx++) {
00155 
00156             _bits[idx] ^= 0xff;
00157         }
00158     }
00159 
00160 private:
00161     u8 _bits[(numBits + NBBY - 1) / NBBY];
00162 };
00163 
00166 template <>
00167 class BitString<0> {
00168 public:
00176     inline BitString(u8 *bitmap = 0, const size_t numBits = 0) :
00177         _bits(bitmap),
00178         _numBits(numBits),
00179         _bitmapSize((numBits + NBBY - 1) / NBBY)
00180     {
00181         if (_bits) {
00182             memset(_bits, 0, _bitmapSize);
00183         }
00184     }
00185 
00190     inline void Set(size_t idx) {
00191         ASSERT(idx < _numBits);
00192         _bits[idx / NBBY] |= 1 << (idx % NBBY);
00193     }
00194 
00199     inline void Clear(size_t idx) {
00200         ASSERT(idx < _numBits);
00201         _bits[idx / NBBY] &= ~(1 << (idx % NBBY));
00202     }
00203 
00209     inline bool IsSet(size_t idx) {
00210         ASSERT(idx < _numBits);
00211         return _bits[idx / NBBY] & (1 << (idx % NBBY));
00212     }
00213 
00219     inline bool IsClear(size_t idx) {
00220         ASSERT(idx < _numBits);
00221         return !IsSet(idx);
00222     }
00223 
00230     inline bool operator[](size_t idx) {
00231         return IsSet(idx);
00232     }
00233 
00238     int FirstSet() {
00239         const size_t numWords = _numBits / (sizeof(uintptr_t) * NBBY);
00240         for (size_t word = 0; word < numWords; word++) {
00241             uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word];
00242             if (x) {
00243                 size_t bit = cpu::bsf(x);
00244                 bit += word * sizeof(uintptr_t) * NBBY;
00245                 return bit;
00246             }
00247         }
00248         /* Check remainder. */
00249         for (size_t idx = numWords * sizeof(uintptr_t) * NBBY;
00250              idx < _numBits;
00251              idx++) {
00252 
00253             if (IsSet(idx)) {
00254                 return idx;
00255             }
00256         }
00257         return -1;
00258     }
00259 
00264     int FirstClear() {
00265         const size_t numWords = _numBits / (sizeof(uintptr_t) * NBBY);
00266         for (size_t word = 0; word < numWords; word++) {
00267             uintptr_t x = static_cast<uintptr_t *>(static_cast<void *>(_bits))[word];
00268             if (x != static_cast<uintptr_t>(~0)) {
00269                 size_t bit = cpu::bsf(~x);
00270                 bit += word * sizeof(uintptr_t) * NBBY;
00271                 return bit;
00272             }
00273         }
00274         /* Check remainder. */
00275         for (size_t idx = numWords * sizeof(uintptr_t) * NBBY;
00276              idx < _numBits;
00277              idx++) {
00278 
00279             if (IsClear(idx)) {
00280                 return idx;
00281             }
00282         }
00283         return -1;
00284     }
00285 
00287     inline void ClearAll() {
00288         memset(_bits, 0, _bitmapSize);
00289     }
00290 
00291     inline void SetAll() {
00292         memset(_bits, 0xff, _bitmapSize);
00293     }
00294 
00295     inline void Invert() {
00296         const size_t numWords = _numBits / (sizeof(uintptr_t) * NBBY);
00297         for (size_t word = 0; word < numWords; word++) {
00298             static_cast<uintptr_t *>(static_cast<void *>(_bits))[word] ^= ~0ul;
00299         }
00300         /* Invert remainder. */
00301         for (size_t idx = numWords * sizeof(uintptr_t);
00302              idx < (_numBits + NBBY - 1) / NBBY;
00303              idx++) {
00304 
00305             _bits[idx] ^= 0xff;
00306         }
00307     }
00308 private:
00309     u8 *_bits;
00310     const size_t _numBits, _bitmapSize;
00311 };
00312 
00313 #endif /* BITSTRING_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines