20 #ifndef SPOT_MISC_BITVECT_HH
21 # define SPOT_MISC_BITVECT_HH
55 bitvect(
size_t size,
size_t block_count);
56 bitvect(
size_t size,
size_t block_count,
bool);
59 typedef unsigned long block_t;
64 storage_(&local_storage_),
72 storage_(&local_storage_)
86 reserve_blocks(other.block_count_);
88 for (
size_t i = 0; i < block_count_; ++i)
89 storage_[i] = other.storage_[i];
95 if (storage_ != &local_storage_)
104 if (new_block_count < block_count_)
106 if (storage_ == &local_storage_)
108 block_t* new_storage_ =
static_cast<block_t*
>
109 (malloc(new_block_count *
sizeof(block_t)));
110 for (
size_t i = 0; i < block_count_; ++i)
111 new_storage_[i] = storage_[i];
112 storage_ = new_storage_;
116 storage_ =
static_cast<block_t*
>
117 (realloc(storage_, new_block_count *
sizeof(block_t)));
119 block_count_ = new_block_count;
125 size_t new_block_count_ = (block_count_ + 1) * 7 / 5;
126 reserve_blocks(new_block_count_);
131 size_t used_blocks()
const
133 const size_t bpb = 8 *
sizeof(block_t);
134 return (size_ + bpb - 1) / bpb;
140 if (size() == capacity())
142 size_t pos = size_++;
152 if (size() + count > capacity())
154 const size_t bpb = 8 *
sizeof(block_t);
158 data &= (1UL << count) - 1;
160 size_t n = size() % bpb;
161 size_t i = size_ / bpb;
170 block_t mask = (1UL << (bpb - n)) - 1;
171 block_t data1 = (data & mask) << n;
174 storage_[i] = (storage_[i] & ~mask) | data1;
177 storage_[i + 1] = data >> (bpb - n);
186 size_t capacity()
const
188 return 8 * block_count_ *
sizeof(block_t);
193 bool get(
size_t pos)
const
196 const size_t bpb = 8 *
sizeof(block_t);
197 return storage_[pos / bpb] & (1UL << (pos % bpb));
202 for (
size_t i = 0; i < block_count_; ++i)
206 bool is_fully_clear()
const
209 for (i = 0; i < block_count_ - 1; ++i)
210 if (storage_[i] != 0)
214 const size_t bpb = 8 *
sizeof(bitvect::block_t);
215 block_t mask = (1UL << (size() % bpb)) - 1;
216 return (storage_[i] & mask) == 0;
219 bool is_fully_set()
const
222 for (i = 0; i < block_count_ - 1; ++i)
223 if (storage_[i] != -1UL)
227 const size_t bpb = 8 *
sizeof(bitvect::block_t);
228 block_t mask = (1UL << (size() % bpb)) - 1;
229 return ((~storage_[i]) & mask) == 0;
234 for (
size_t i = 0; i < block_count_; ++i)
240 for (
size_t i = 0; i < block_count_; ++i)
241 storage_[i] = ~storage_[i];
247 const size_t bpb = 8 *
sizeof(block_t);
248 storage_[pos / bpb] |= 1UL << (pos % bpb);
251 void clear(
size_t pos)
254 const size_t bpb = 8 *
sizeof(block_t);
255 storage_[pos / bpb] &= ~(1UL << (pos % bpb));
258 void flip(
size_t pos)
261 const size_t bpb = 8 *
sizeof(block_t);
262 storage_[pos / bpb] ^= (1UL << (pos % bpb));
266 bitvect& operator|=(
const bitvect& other)
268 assert(other.size_ <= size_);
269 unsigned m = std::min(other.block_count_, block_count_);
270 for (
size_t i = 0; i < m; ++i)
271 storage_[i] |= other.storage_[i];
275 bitvect& operator&=(
const bitvect& other)
277 assert(other.size_ <= size_);
278 unsigned m = std::min(other.block_count_, block_count_);
279 for (
size_t i = 0; i < m; ++i)
280 storage_[i] &= other.storage_[i];
284 bitvect& operator^=(
const bitvect& other)
286 assert(other.size_ <= size_);
287 unsigned m = std::min(other.block_count_, block_count_);
288 for (
size_t i = 0; i < m; ++i)
289 storage_[i] ^= other.storage_[i];
293 bitvect& operator-=(
const bitvect& other)
295 assert(other.block_count_ <= block_count_);
296 for (
size_t i = 0; i < other.block_count_; ++i)
297 storage_[i] &= ~other.storage_[i];
301 bool operator==(
const bitvect& other)
const
303 if (other.size_ != size_)
308 size_t m = other.used_blocks();
309 for (i = 0; i < m - 1; ++i)
310 if (storage_[i] != other.storage_[i])
314 const size_t bpb = 8 *
sizeof(bitvect::block_t);
315 block_t mask = (1UL << (size() % bpb)) - 1;
316 return (storage_[i] & mask) == (other.storage_[i] & mask);
319 bool operator!=(
const bitvect& other)
const
321 return !(*
this == other);
324 bool operator<(
const bitvect& other)
const
326 if (size_ != other.size_)
327 return size_ < other.size_;
331 size_t m = other.used_blocks();
332 for (i = 0; i < m - 1; ++i)
333 if (storage_[i] > other.storage_[i])
337 const size_t bpb = 8 *
sizeof(bitvect::block_t);
338 block_t mask = (1UL << (size() % bpb)) - 1;
339 return (storage_[i] & mask) < (other.storage_[i] & mask);
342 bool operator>=(
const bitvect& other)
const
344 return !(*
this < other);
347 bool operator>(
const bitvect& other)
const
349 return other < *
this;
352 bool operator<=(
const bitvect& other)
const
354 return !(other < *
this);
361 bitvect* extract_range(
size_t begin,
size_t end)
363 assert(begin <= end);
364 assert(end <= size());
365 size_t count = end - begin;
372 const size_t bpb = 8 *
sizeof(bitvect::block_t);
374 size_t indexb = begin / bpb;
375 unsigned bitb = begin % bpb;
376 size_t indexe = (end - 1) / bpb;
378 if (indexb == indexe)
380 block_t data = storage_[indexb];
382 res->push_back(data, count);
386 block_t data = storage_[indexb];
388 res->push_back(data, bpb - bitb);
393 res->push_back(storage_[indexb], bpb);
395 assert(indexb != indexe || count == 0);
400 assert(indexb == indexe);
401 assert(count == end % bpb);
402 res->push_back(storage_[indexb], count);
408 friend SPOT_API bitvect*
412 friend SPOT_API std::ostream& operator<<(std::ostream&,
416 friend SPOT_API bitvect_array*
426 block_t local_storage_;
442 SPOT_LOCAL
void operator=(
const bitvect_array&);
448 for (
size_t i = 0; i < size_; ++i)
461 assert(index < size_);
462 return *
reinterpret_cast<bitvect*
>(storage_ + index * bvsize_);
468 assert(index < size_);
469 return *
reinterpret_cast<const bitvect*
>(storage_ + index * bvsize_);
472 friend SPOT_API bitvect_array*
478 friend SPOT_API std::ostream& operator<<(std::ostream&,
479 const bitvect_array&);
491 #endif // SPOT_MISC_BITVECT_HH