00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "BitSet.h"
00021
00022 namespace mdw
00023 {
00024 namespace
00025 {
00026 typedef unsigned long internalItemType;
00027 static const int internalItemSize = 64;
00028 static const int positionShift = 6;
00029 static const int positionMask = 0x3F;
00030 static const internalItemType totalMask = 0xFFFFFFFFFFFFFFFFL;
00031 static const internalItemType zero = 0L;
00032
00033
00034 int numberOfLeadingZeros (internalItemType i)
00035 {
00036 if (i == 0L)
00037 return 64;
00038 int n = 1;
00039 int x = (int) (i >> 32);
00040 if (x == 0)
00041 {
00042 n += 32;
00043 x = (int) i;
00044 }
00045 if (x >> 16 == 0)
00046 {
00047 n += 16;
00048 x <<= 16;
00049 }
00050 if (x >> 24 == 0)
00051 {
00052 n += 8;
00053 x <<= 8;
00054 }
00055 if (x >> 28 == 0)
00056 {
00057 n += 4;
00058 x <<= 4;
00059 }
00060 if (x >> 30 == 0)
00061 {
00062 n += 2;
00063 x <<= 2;
00064 }
00065 n -= x >> 31;
00066 return n;
00067 }
00068
00069
00070 }
00071
00072 BitSet::BitSet (int size)
00073 {
00074 int arraySize = ( (size - 1) / internalItemSize) + 1;
00075 _array = new internalItemType[arraySize];
00076 _size = size;
00077 }
00078
00079
00080 BitSet::~BitSet()
00081 {
00082 delete[] ( (internalItemType*) _array);
00083 }
00084
00085 void BitSet::clearAll()
00086 {
00087 int arraySize = ( (_size - 1) / internalItemSize) + 1;
00088 for (int i = 0; i < arraySize; ++i)
00089 {
00090 ( (internalItemType*) _array) [i] = zero;
00091 }
00092 }
00093
00094 void BitSet::clearBetween (int from, int to)
00095 {
00096 ++from;
00097 --to;
00098 int posArrayFrom = from >> positionShift;
00099 int posItemFrom = from & positionMask;
00100 int posArrayTo = to >> positionShift;
00101 int posItemTo = to & positionMask;
00102 if (posArrayFrom == posArrayTo)
00103 {
00104 internalItemType mask = (totalMask << posItemFrom) & totalMask >> (internalItemSize - 1 - posItemTo);
00105 ( (internalItemType*) _array) [posArrayFrom] &= ~mask;
00106 }
00107 else
00108 {
00109 ( (internalItemType*) _array) [posArrayFrom] &= ~ (totalMask << posItemFrom);
00110 ( (internalItemType*) _array) [posArrayTo] &= ~ (totalMask >> (internalItemSize - 1 - posItemTo));
00111 for (int i = posArrayFrom + 1; i < posArrayTo; ++i)
00112 {
00113 ( (internalItemType*) _array) [i] = zero;
00114 }
00115 }
00116 }
00117
00118 bool BitSet::isSet (int pos)
00119 {
00120 int positionArray = pos >> positionShift;
00121 internalItemType localMask = 1L << (pos & positionMask);
00122 return ( ( (internalItemType*) _array) [positionArray] & localMask) == localMask;;
00123 }
00124
00125 void BitSet::set (int pos)
00126 {
00127 int positionArray = pos >> positionShift;
00128 internalItemType localMask = 1L << (pos & positionMask);
00129 ( (internalItemType*) _array) [positionArray] |= localMask;
00130 }
00131
00132 void BitSet::clear (int pos)
00133 {
00134 int positionArray = pos >> positionShift;
00135 internalItemType localMask = 1L << (pos & positionMask);
00136 ( (internalItemType*) _array) [positionArray] &= ~localMask;
00137 }
00138
00139 int BitSet::getPreviousSet (int pos)
00140 {
00141 if (pos == 0)
00142 {
00143 return -1;
00144 }
00145 pos--;
00146 int positionArray = pos >> positionShift;
00147 int positionItem = pos & positionMask;
00148
00149 internalItemType mask = ~ (totalMask << positionItem + 1);
00150 internalItemType word = ( (internalItemType*) _array) [positionArray] & mask;
00151
00152 while (true)
00153 {
00154 if (word != 0)
00155 {
00156 return (positionArray * internalItemSize) + internalItemSize - 1 - numberOfLeadingZeros (word);
00157 }
00158
00159 if (positionArray == 0)
00160 {
00161 return -1;
00162 }
00163 --positionArray;
00164 word = ( (internalItemType*) _array) [positionArray];
00165 }
00166
00167
00168 }
00169
00170 }