2 #include "bit-vector.hpp"
5 static inline uint8_t pow2_mult8(uint8_t x){
6 return (~((x & (x-1))==0) + 1) & (x >> 3);
10 static inline size_t uint32bits(size_t bits){
11 return ((bits-1) / W) + 1;
15 static void array_copy(const uint32_t * src, uint32_t * dst, size_t len)
17 for(size_t i = 0; i < len; i++) dst[i] = src[i];
20 size_t bit_vector::allocforsize(size_t bits)
23 while (uint32bits(bits) >= i)
28 void bit_vector::grow(size_t alloc)
33 uint32_t* vector = new uint32_t[ alloc ];
35 array_copy(_vector,vector,_alloc);
37 if (!_leaked) delete [] _vector;
45 bit_vector::bit_vector (size_t len, size_t blen, uint32_t init)
54 _alloc = uint32bits(_size);
55 _vector = new uint32_t[_alloc];
57 for(size_t i = 0; i < len; ++i) set_field(i,blen, init);
61 bit_vector::bit_vector(int fd)
63 ssize_t toread = sizeof(size_t);
64 auto msg = std::runtime_error("I/O error in bit_vector::read");
66 if (toread != read(fd, &_size, toread))
69 _alloc = uint32bits(_size);
70 _vector = new uint32_t[_alloc];
72 toread = sizeof(uint32_t);
73 for(size_t i = 0; i < _alloc; ++i)
74 if (toread != read(fd, &_vector[i], toread)){
83 bit_vector::bit_vector (const bit_vector& src)
87 _vector = new uint32_t[ _alloc = src._alloc ];
88 array_copy(src._vector,_vector,_alloc);
91 bit_vector & bit_vector::operator=(const bit_vector& src)
96 _vector = new uint32_t[ _alloc = src._alloc ];
97 array_copy(src._vector,_vector,_alloc);
103 bit_vector::~bit_vector()
105 if (!_leaked) delete [] _vector;
113 void bit_vector::save(int fd) const
116 ssize_t towrite = sizeof(size_t);
117 std::string msg = "I/O error in bit_vector::write";
119 if (towrite != write(fd,&_size,towrite))
122 towrite = sizeof(uint32_t);
124 for (size_t i = 0; i < _alloc; ++i)
125 if (towrite != write(fd, &_vector[i], towrite))
133 void bit_vector::pack()
136 size_t nalloc = uint32bits(_size);
137 uint32_t * nvector = new uint32_t[nalloc];
138 array_copy(_vector, nvector, nalloc);
139 if (!_leaked && _vector) delete [] _vector;
141 this->_vector = nvector;
142 this->_leaked = false;
146 //sets the idxth bit to b
147 void bit_vector::set(size_t idx, bool b)
152 grow(allocforsize(idx+1));
155 uint32_t mask = 1 << (W - 1 - j);
162 void bit_vector::push_back(bool b)
167 bool bit_vector::pop_back()
170 return unsafe_get(_size);
173 bool bit_vector::flip(size_t idx)
180 void bit_vector::set_field(size_t index, size_t len, uint32_t v)
182 size_t i=index*len/W, j=index*len-i*W;
184 grow(allocforsize((index+2)*len));
186 if ((index+1)*len >= _size)
187 _size = (index+2)*len;
188 } else if (index*len >= _size)
189 _size = (index+1)*len;
191 uint32_t mask = ((j+len) < W ? ~0U << (j+len) : 0)
192 | ((W-j) < W ? ~0U >> (W-j) : 0);
193 _vector[i] = (_vector[i] & mask) | v << j;
196 mask = ((~0U) << (len+j-W));
197 _vector[i+1] = (_vector[i+1] & mask)| v >> (W-j);
201 bool bit_vector::get(size_t index) const
204 throw (std::out_of_range("bit_vector::get"));
206 return unsafe_get(index);
209 uint32_t bit_vector::get_field(size_t index, size_t len) const
211 if ((index+1)*len > _size)
212 throw (std::out_of_range("bit_vector::get_field: index out of bound"));
214 throw (std::invalid_argument("bit_vector::get_field: len > 32" ));
216 return unsafe_get_field(index, len);
219 uint32_t * bit_vector::get_vector() const
221 uint32_t * vector = new uint32_t[_alloc];
222 array_copy(_vector,vector,_alloc);