20 #ifndef SPOT_MISC_BITVECT_HH
21 # define SPOT_MISC_BITVECT_HH
34 class SPOT_API bitvect;
35 class SPOT_API bitvect_array;
53 bitvect(
size_t size,
size_t block_count);
54 bitvect(
size_t size,
size_t block_count,
bool);
57 typedef unsigned long block_t;
62 storage_(&local_storage_),
70 storage_(&local_storage_)
84 reserve_blocks(other.block_count_);
86 for (
size_t i = 0; i < block_count_; ++i)
87 storage_[i] = other.storage_[i];
93 if (storage_ != &local_storage_)
102 if (new_block_count < block_count_)
104 if (storage_ == &local_storage_)
106 block_t* new_storage_ =
static_cast<block_t*
>
107 (malloc(new_block_count *
sizeof(block_t)));
108 for (
size_t i = 0; i < block_count_; ++i)
109 new_storage_[i] = storage_[i];
110 storage_ = new_storage_;
114 storage_ =
static_cast<block_t*
>
115 (realloc(storage_, new_block_count *
sizeof(block_t)));
117 block_count_ = new_block_count;
123 size_t new_block_count_ = (block_count_ + 1) * 7 / 5;
124 reserve_blocks(new_block_count_);
131 if (size() == capacity())
133 size_t pos = size_++;
143 if (size() + count > capacity())
145 const size_t bpb = 8 *
sizeof(block_t);
149 data &= (1UL << count) - 1;
151 size_t n = size() % bpb;
152 size_t i = size_ / bpb;
161 block_t mask = (1UL << (bpb - n)) - 1;
162 block_t data1 = (data & mask) << n;
165 storage_[i] = (storage_[i] & ~mask) | data1;
168 storage_[i + 1] = data >> (bpb - n);
177 size_t capacity()
const
179 return 8 * block_count_ *
sizeof(block_t);
184 bool get(
size_t pos)
const
187 const size_t bpb = 8 *
sizeof(block_t);
188 return storage_[pos / bpb] & (1UL << (pos % bpb));
193 for (
size_t i = 0; i < block_count_; ++i)
197 bool is_fully_clear()
const
200 for (i = 0; i < block_count_ - 1; ++i)
201 if (storage_[i] != 0)
205 const size_t bpb = 8 *
sizeof(bitvect::block_t);
206 block_t mask = (1UL << (size() % bpb)) - 1;
207 return (storage_[i] & mask) == 0;
210 bool is_fully_set()
const
213 for (i = 0; i < block_count_ - 1; ++i)
214 if (storage_[i] != -1UL)
218 const size_t bpb = 8 *
sizeof(bitvect::block_t);
219 block_t mask = (1UL << (size() % bpb)) - 1;
220 return ((~storage_[i]) & mask) == 0;
225 for (
size_t i = 0; i < block_count_; ++i)
231 for (
size_t i = 0; i < block_count_; ++i)
232 storage_[i] = ~storage_[i];
238 const size_t bpb = 8 *
sizeof(block_t);
239 storage_[pos / bpb] |= 1UL << (pos % bpb);
242 void clear(
size_t pos)
245 const size_t bpb = 8 *
sizeof(block_t);
246 storage_[pos / bpb] &= ~(1UL << (pos % bpb));
249 void flip(
size_t pos)
252 const size_t bpb = 8 *
sizeof(block_t);
253 storage_[pos / bpb] ^= (1UL << (pos % bpb));
257 bitvect& operator|=(
const bitvect& other)
259 assert(other.block_count_ <= block_count_);
260 for (
size_t i = 0; i < other.block_count_; ++i)
261 storage_[i] |= other.storage_[i];
265 bitvect& operator&=(
const bitvect& other)
267 assert(other.block_count_ <= block_count_);
268 for (
size_t i = 0; i < other.block_count_; ++i)
269 storage_[i] &= other.storage_[i];
273 bitvect& operator^=(
const bitvect& other)
275 assert(other.block_count_ <= block_count_);
276 for (
size_t i = 0; i < other.block_count_; ++i)
277 storage_[i] ^= other.storage_[i];
281 bitvect& operator-=(
const bitvect& other)
283 assert(other.block_count_ <= block_count_);
284 for (
size_t i = 0; i < other.block_count_; ++i)
285 storage_[i] &= ~other.storage_[i];
289 bool operator==(
const bitvect& other)
const
291 if (other.block_count_ != block_count_)
294 for (i = 0; i < other.block_count_ - 1; ++i)
295 if (storage_[i] != other.storage_[i])
299 const size_t bpb = 8 *
sizeof(bitvect::block_t);
300 block_t mask = (1UL << (size() % bpb)) - 1;
301 return (storage_[i] & mask) == (other.storage_[i] & mask);
304 bool operator!=(
const bitvect& other)
const
306 return !(*
this == other);
309 bool operator<(
const bitvect& other)
const
311 if (block_count_ != other.block_count_)
312 return block_count_ < other.block_count_;
314 for (i = 0; i < other.block_count_ - 1; ++i)
315 if (storage_[i] > other.storage_[i])
319 const size_t bpb = 8 *
sizeof(bitvect::block_t);
320 block_t mask = (1UL << (size() % bpb)) - 1;
321 return (storage_[i] & mask) < (other.storage_[i] & mask);
324 bool operator>=(
const bitvect& other)
const
326 return !(*
this < other);
329 bool operator>(
const bitvect& other)
const
331 return other < *
this;
334 bool operator<=(
const bitvect& other)
const
336 return !(other < *
this);
343 bitvect* extract_range(
size_t begin,
size_t end)
345 assert(begin <= end);
346 assert(end <= size());
347 size_t count = end - begin;
354 const size_t bpb = 8 *
sizeof(bitvect::block_t);
356 size_t indexb = begin / bpb;
357 unsigned bitb = begin % bpb;
358 size_t indexe = (end - 1) / bpb;
360 if (indexb == indexe)
362 block_t data = storage_[indexb];
364 res->push_back(data, count);
368 block_t data = storage_[indexb];
370 res->push_back(data, bpb - bitb);
375 res->push_back(storage_[indexb], bpb);
377 assert(indexb != indexe || bpb == 0);
382 assert(indexb == indexe);
383 assert(count == end % bpb);
384 res->push_back(storage_[indexb], count);
390 friend SPOT_API bitvect*
394 friend SPOT_API std::ostream& operator<<(std::ostream&,
398 friend SPOT_API bitvect_array*
408 block_t local_storage_;
424 SPOT_LOCAL
void operator=(
const bitvect_array&);
430 for (
size_t i = 0; i < size_; ++i)
443 assert(index < size_);
444 return *
reinterpret_cast<bitvect*
>(storage_ + index * bvsize_);
450 assert(index < size_);
451 return *
reinterpret_cast<const bitvect*
>(storage_ + index * bvsize_);
454 friend SPOT_API bitvect_array*
460 friend SPOT_API std::ostream& operator<<(std::ostream&,
461 const bitvect_array&);
473 #endif // SPOT_MISC_BITVECT_HH