00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00033 #ifndef _BITSTRING_H_
00034 #define _BITSTRING_H_
00035
00036 #include <assert.h>
00037
00038 template <int N>
00039 class BitString {
00040 public:
00041
00042 BitString (void) {
00043 clear();
00044 }
00045
00046 inline void clear (void) {
00047 for (int i = 0; i < NUM_ULONGS; i++) {
00048 B[i] = ALL_ALLOCATED;
00049 }
00050 firstPos = 0;
00051 }
00052
00053
00054 int allocate (int length, int alignment) {
00055
00056 for (int bitPos = firstPos; bitPos < N; ) {
00057
00058
00059 if (B[bitPos >> SHIFTS_PER_ULONG] == ALL_ALLOCATED) {
00060 bitPos = ((bitPos >> SHIFTS_PER_ULONG) + 1) << SHIFTS_PER_ULONG;
00061
00062 while ((bitPos % alignment) != 0) {
00063 bitPos++;
00064 }
00065 continue;
00066 }
00067
00068 if (get(bitPos)) {
00069 bitPos += alignment;
00070 continue;
00071 }
00072
00073 bool gotOne = true;
00074 for (int j = 0; j < length; j++) {
00075 if (get(bitPos + j)) {
00076 gotOne = false;
00077 bitPos += j;
00078
00079 while ((bitPos % alignment) != 0) {
00080 bitPos++;
00081 }
00082 break;
00083 }
00084 }
00085 if (gotOne) {
00086
00087 for (int j = 0; j < length; j++) {
00088 set(bitPos + j);
00089 }
00090 return bitPos;
00091 }
00092 }
00093
00094 return -1;
00095 }
00096
00097 void free (int bitPos, int length) {
00098 for (int j = bitPos; j < bitPos + length; j++) {
00099 reset (j);
00100 }
00101 }
00102
00103 #if 0
00104 inline int first (void) const {
00105 for (int i = 0; i < NUM_ULONGS; i++) {
00106 if (B[i] > 0) {
00107 unsigned long index = 1U << (BITS_PER_ULONG-1);
00108 for (int j = 0; j < BITS_PER_ULONG; j++) {
00109 if (B[i] & index) {
00110 return j + i * BITS_PER_ULONG;
00111 }
00112 index >>= 1;
00113 }
00114 }
00115 }
00116 return -1;
00117 }
00118 #endif
00119
00120 inline int firstAfter (const int index) const {
00121 #if 0
00122 for (int i = index; i < N; i++ ) {
00123 int ind = i >> SHIFTS_PER_ULONG;
00124 if (B[ind] & (1U << (i & (BITS_PER_ULONG - 1)))) {
00125 return i;
00126 }
00127 }
00128 return -1;
00129 #else
00130 int indmask = index - (index >> SHIFTS_PER_ULONG) * BITS_PER_ULONG;
00131 for (int i = index >> SHIFTS_PER_ULONG; i < NUM_ULONGS; i++) {
00132 if (B[i]) {
00133 unsigned long bitval = B[i];
00134 bitval &= ~((1 << (indmask & (BITS_PER_ULONG - 1))) - 1);
00135 if (bitval) {
00136 return (i * BITS_PER_ULONG + lsb(bitval));
00137 }
00138 }
00139 indmask = indmask - BITS_PER_ULONG;
00140 if (indmask < 0) {
00141 indmask = 0;
00142 }
00143 }
00144 return -1;
00145 #endif
00146 }
00147
00148 inline bool get (const int index) const {
00149 assert (index >= 0);
00150 assert (index < N);
00151 int ind = index >> SHIFTS_PER_ULONG;
00152 assert (ind >= 0);
00153 assert (ind < NUM_ULONGS);
00154 return (B[ind] & (1U << (index & (BITS_PER_ULONG - 1))));
00155 }
00156
00157 inline void set (const int index) {
00158 assert (index >= 0);
00159 assert (index < N);
00160 int ind = index >> SHIFTS_PER_ULONG;
00161 assert (ind >= 0);
00162 assert (ind < NUM_ULONGS);
00163 B[ind] |= (1U << (index & (BITS_PER_ULONG - 1)));
00164 if (index < firstPos) {
00165 firstPos = index;
00166 }
00167 }
00168
00169 inline void reset (const int index) {
00170 assert (index >= 0);
00171 assert (index < N);
00172 int ind = index >> SHIFTS_PER_ULONG;
00173 assert (ind >= 0);
00174 assert (ind < NUM_ULONGS);
00175 B[ind] &= ~(1U << (index & (BITS_PER_ULONG - 1)));
00176 }
00177
00178 unsigned long operator() (int index) {
00179 assert (index >= 0);
00180 assert (index < NUM_ULONGS);
00181 return B[index];
00182 }
00183
00184
00185 private:
00186
00187 #if 1 // (sizeof(unsigned long),4)
00188 enum { BITS_PER_ULONG = 32 };
00189 enum { SHIFTS_PER_ULONG = 5 };
00190 #else
00191 enum { BITS_PER_ULONG = 64 };
00192 enum { SHIFTS_PER_ULONG = 6 };
00193 #endif
00194
00195 enum { ALL_ALLOCATED = (unsigned long) -1 };
00196 enum { MAX_BITS = (N + BITS_PER_ULONG - 1) & ~(BITS_PER_ULONG - 1) };
00197 enum { NUM_ULONGS = MAX_BITS / BITS_PER_ULONG };
00198
00199 unsigned long B[NUM_ULONGS];
00200
00202 int firstPos;
00203
00204 inline static int lsb (unsigned long b) {
00205 static const int index32[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 };
00206 const unsigned long debruijn32 = 0x077CB531UL;
00207 b &= (unsigned long) -((signed long) b);
00208 b *= debruijn32;
00209 b >>= 27;
00210 assert (b >= 0);
00211 assert (b < 32);
00212 return index32[b];
00213 }
00214
00215 };
00216
00217
00218 #endif