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
00027
00028 #ifndef _terimber_bitset_hpp_
00029 #define _terimber_bitset_hpp_
00030
00031 #include "base/bitset.h"
00032
00033 BEGIN_TERIMBER_NAMESPACE
00034 #pragma pack(4)
00035
00036 static const unsigned char low_zero_in_byte[] =
00037 {
00038 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00039 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
00040 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00041 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6,
00042 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00043 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
00044 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00045 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7,
00046 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00047 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
00048 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00049 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6,
00050 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00051 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,
00052 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,
00053 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0xff
00054 };
00055
00056
00057 inline
00058 base_bitset::base_bitset(size_t capacity) : _capacity(capacity), _bits(0)
00059 {
00060 }
00061
00062 inline
00063 bool
00064 base_bitset::set(size_t index, bool value)
00065 {
00066
00067 if (index >= _capacity)
00068 return false;
00069
00070
00071 size_t off = offset(index);
00072
00073
00074 if (value)
00075 _bits[off] |= mask(index);
00076 else
00077 _bits[off] &= ~(mask(index));
00078
00079 return true;
00080 }
00081
00082 inline
00083 bool
00084 base_bitset::get(size_t index) const
00085 {
00086
00087 if (index >= _capacity)
00088 return false;
00089
00090
00091 size_t off = offset(index);
00092
00093 return 0 != (_bits[off] & mask(index));
00094 }
00095
00096 inline
00097 bool
00098 base_bitset::find_first_free(size_t& index) const
00099 {
00100
00101 const unsigned char* begin = _bits;
00102 const unsigned char* ptr = begin;
00103 const unsigned char* end = _bits + get_byte_len(_capacity);
00104
00105
00106 while (ptr != end && *ptr == 0xff) ++ptr;
00107
00108 if (ptr == end)
00109 return false;
00110
00111
00112 index = bs_bits_in_byte * (ptr - begin) + low_zero_in_byte[*ptr];
00113
00114 return index < _capacity;
00115 }
00116
00117
00118 inline
00119 size_t
00120 base_bitset::get_byte_len(size_t bitlen)
00121 {
00122
00123 return (bitlen >> bs_offset) + ((bitlen & bs_mask) != 0 ? 1 : 0);
00124 }
00125
00126
00127 inline
00128 size_t
00129 base_bitset::offset(size_t index)
00130 {
00131 return index >> bs_offset;
00132 }
00133
00134
00135 inline
00136 unsigned char
00137 base_bitset::mask(size_t index)
00138 {
00139 return (0x01 << (unsigned char)(index & bs_mask));
00140 }
00141
00142 inline
00143 bool
00144 base_bitset::operator==(const base_bitset& x) const
00145 {
00146
00147 if (_capacity != x._capacity)
00148 return false;
00149
00150 if (!_capacity)
00151 return true;
00152
00153 return !memcmp(_bits, x._bits, get_byte_len(_capacity));
00154 }
00155
00156 inline
00157 bool
00158 base_bitset::operator!=(const base_bitset& x) const
00159 {
00160 return !operator==(x);
00161 }
00162
00163 inline
00164 base_bitset&
00165 base_bitset::operator|=(const base_bitset& x)
00166 {
00167 assert(_capacity = x._capacity);
00168 size_t len = get_byte_len(_capacity);
00169 for (size_t index = 0; index < len; ++index)
00170 _bits[index] |= x._bits[index];
00171 return *this;
00172 }
00173
00174 inline
00175 base_bitset&
00176 base_bitset::operator&=(const base_bitset& x)
00177 {
00178 assert(_capacity = x._capacity);
00179 size_t len = get_byte_len(_capacity);
00180 for (size_t index = 0; index < len; ++index)
00181 _bits[index] &= x._bits[index];
00182 return *this;
00183 }
00184
00185 inline
00186 void
00187 base_bitset::reset()
00188 {
00189 if (_capacity)
00190 memset(_bits, 0, get_byte_len(_capacity));
00191 }
00192
00193 inline
00194 bool
00195 base_bitset::empty() const
00196 {
00197
00198 const unsigned char* begin = _bits;
00199 const unsigned char* ptr = begin;
00200 const unsigned char* end = _bits + get_byte_len(_capacity);
00201
00202
00203 while (ptr != end && *ptr == 0x00) ++ptr;
00204
00205 return ptr == end;
00206 }
00207
00208 inline
00209 bool
00210 base_bitset::operator<(const base_bitset& x) const
00211 {
00212 if (!_capacity)
00213 return x._capacity != 0;
00214 else if (!x._capacity)
00215 return false;
00216 else
00217 {
00218 size_t min_capacity = __min(_capacity, x._capacity);
00219 int ret = memcmp(_bits, x._bits, get_byte_len(min_capacity));
00220 return ret ? ret < 0 : _capacity < x._capacity;
00221 }
00222 }
00224 inline
00225 _bitset::_bitset() :
00226 base_bitset(0)
00227 {
00228 }
00229
00230 inline
00231 _bitset::_bitset(TERIMBER::byte_allocator& all, size_t capacity) :
00232 base_bitset(capacity)
00233 {
00234 size_t len = get_byte_len(capacity);
00235 if (len)
00236 {
00237 _bits = (unsigned char*)all.allocate(len);
00238 memset(_bits, 0, len);
00239 }
00240 }
00241
00242 inline
00243 _bitset&
00244 _bitset::operator=(const _bitset& x)
00245 {
00246 _bits = x._bits;
00247 _capacity = x._capacity;
00248 return *this;
00249 }
00250
00251 inline
00252 _bitset&
00253 _bitset::assign(byte_allocator& all, const _bitset& x)
00254 {
00255 _capacity = x._capacity;
00256 size_t len = get_byte_len(x._capacity);
00257 if (len)
00258 {
00259 _bits = (unsigned char*)all.allocate(len);
00260 memcpy(_bits, x._bits, len);
00261 }
00262 else
00263 _bits = 0;
00264
00265 return *this;
00266 }
00267
00268 inline
00269 _bitset&
00270 _bitset::resize(byte_allocator& all, size_t capacity)
00271 {
00272 size_t oldlen = get_byte_len(_capacity);
00273 size_t newlen = get_byte_len(capacity);
00274 if (newlen > oldlen)
00275 {
00276
00277 unsigned char* bits = (unsigned char*)all.allocate(newlen);
00278
00279 if (oldlen)
00280 memcpy(bits, _bits, oldlen);
00281
00282 memset(bits + oldlen, 0, newlen - oldlen);
00283
00284 _bits = bits;
00285 }
00286 else if (!newlen)
00287 _bits = 0;
00288
00289 _capacity = capacity;
00290 return *this;
00291
00292 }
00293
00294 inline
00295 void
00296 _bitset::clear()
00297 {
00298 if (_capacity)
00299 _bits = 0, _capacity = 0;
00300 }
00301
00303 inline
00304 bitset::bitset() :
00305 base_bitset(0)
00306 {
00307 }
00308
00309 inline
00310 bitset::bitset(size_t capacity) :
00311 base_bitset(capacity)
00312 {
00313 size_t len = get_byte_len(capacity);
00314 if (len)
00315 {
00316 _bits = (unsigned char*)malloc(len);
00317 memset(_bits, 0, len);
00318 }
00319 }
00320
00321 inline
00322 bitset::~bitset()
00323 {
00324 free(_bits);
00325 }
00326
00327 inline
00328 bitset&
00329 bitset::operator=(const bitset& x)
00330 {
00331 if (_bits)
00332 free (_bits), _bits = 0;
00333
00334 _capacity = x._capacity;
00335 size_t len = get_byte_len(_capacity);
00336 if (len)
00337 {
00338 _bits = (unsigned char*)malloc(len);
00339 memcpy(_bits, x._bits, len);
00340 }
00341
00342 return *this;
00343 }
00344
00345 inline
00346 bitset&
00347 bitset::resize(size_t capacity)
00348 {
00349 size_t oldlen = get_byte_len(_capacity);
00350 size_t newlen = get_byte_len(capacity);
00351 if (newlen > oldlen)
00352 {
00353
00354 unsigned char* bits = (unsigned char*)malloc(newlen);
00355
00356 if (oldlen)
00357 memcpy(bits, _bits, oldlen);
00358
00359 memset(bits + oldlen, 0, newlen - oldlen);
00360
00361 _bits = bits;
00362 }
00363 else if (!newlen && _bits)
00364 {
00365 free(_bits), _bits = 0;
00366 }
00367
00368 _capacity = capacity;
00369 return *this;
00370 }
00371
00373 inline
00374 void
00375 bitset::clear()
00376 {
00377 if (_capacity)
00378 free(_bits), _bits = 0, _capacity = 0;
00379 }
00380
00381 #pragma pack()
00382 END_TERIMBER_NAMESPACE
00383
00384 #endif
00385