3 #include "bit-vector.hpp"
9 static inline uint8_t pow2_mult8(uint8_t x){
10 return (~((x & (x-1))==0) + 1) & (x >> 3);
14 static inline size_t uint32bits(size_t bits){
15 return ((bits-1) / W) + 1;
19 static void array_copy(const uint32_t * src, uint32_t * dst, size_t len)
21 for(size_t i = 0; i < len; i++) dst[i] = src[i];
24 size_t bit_vector::allocforsize(size_t bits)
27 while (uint32bits(bits) >= i)
32 void bit_vector::grow(size_t alloc)
37 uint32_t* vector = new uint32_t[ alloc ];
39 array_copy(_vector,vector,_alloc);
41 if (!_leaked) delete [] _vector;
49 bit_vector::bit_vector (size_t len, size_t blen, uint32_t init)
58 _alloc = uint32bits(_size);
59 _vector = new uint32_t[_alloc];
61 for(size_t i = 0; i < len; ++i) set_field(i,blen, init);
65 bit_vector::bit_vector(int fd)
67 ssize_t toread = sizeof(size_t);
68 auto msg = std::runtime_error("I/O error in bit_vector::read");
70 if (toread != read(fd, &_size, toread))
73 _alloc = uint32bits(_size);
74 _vector = new uint32_t[_alloc];
76 toread = sizeof(uint32_t);
77 for(size_t i = 0; i < _alloc; ++i)
78 if (toread != read(fd, &_vector[i], toread)){
87 bit_vector::bit_vector (const bit_vector& src)
91 _vector = new uint32_t[ _alloc = src._alloc ];
92 array_copy(src._vector,_vector,_alloc);
95 bit_vector & bit_vector::operator=(const bit_vector& src)
100 _vector = new uint32_t[ _alloc = src._alloc ];
101 array_copy(src._vector,_vector,_alloc);
107 bit_vector::~bit_vector()
109 if (!_leaked) delete [] _vector;
117 void bit_vector::save(int fd) const
120 ssize_t towrite = sizeof(size_t);
121 std::string msg = "I/O error in bit_vector::write";
123 if (towrite != write(fd,&_size,towrite))
126 towrite = sizeof(uint32_t);
128 for (size_t i = 0; i < _alloc; ++i)
129 if (towrite != write(fd, &_vector[i], towrite))
137 void bit_vector::pack()
140 size_t nalloc = uint32bits(_size);
141 uint32_t * nvector = new uint32_t[nalloc];
142 array_copy(_vector, nvector, nalloc);
143 if (!_leaked && _vector) delete [] _vector;
145 this->_vector = nvector;
146 this->_leaked = false;
150 //sets the idxth bit to b
151 void bit_vector::set(size_t idx, bool b)
155 grow(allocforsize(idx+1));
158 uint32_t mask = 1 << (W - 1 - j);
164 void bit_vector::set_le(size_t idx, bool b)
168 grow(allocforsize(idx+1));
171 uint32_t mask = 1 << j;
178 void bit_vector::push_back(bool b)
183 bool bit_vector::pop_back()
186 return unsafe_get(_size);
189 bool bit_vector::flip(size_t idx)
196 void bit_vector::set_field(size_t index, size_t len, uint32_t v)
198 size_t i=index*len/W, j=index*len-i*W;
200 grow(allocforsize((index+2)*len));
202 if ((index+1)*len >= _size)
203 _size = (index+2)*len;
204 } else if (index*len >= _size)
205 _size = (index+1)*len;
207 uint32_t mask = ((j+len) < W ? ~0U << (j+len) : 0)
208 | ((W-j) < W ? ~0U >> (W-j) : 0);
209 _vector[i] = (_vector[i] & mask) | v << j;
212 mask = ((~0U) << (len+j-W));
213 _vector[i+1] = (_vector[i+1] & mask)| v >> (W-j);
217 bool bit_vector::get(size_t index) const
220 throw (std::out_of_range("bit_vector::get"));
222 return unsafe_get(index);
225 uint32_t bit_vector::get_field(size_t index, size_t len) const
227 if ((index+1)*len > _size)
228 throw (std::out_of_range("bit_vector::get_field: index out of bound"));
230 throw (std::invalid_argument("bit_vector::get_field: len > 32" ));
232 return unsafe_get_field(index, len);
235 uint32_t * bit_vector::get_vector() const
237 uint32_t * vector = new uint32_t[_alloc];
238 array_copy(_vector,vector,_alloc);
242 void bit_vector::debug(void) const
244 for(size_t i = 0; i < _size; i++)
245 fprintf(stderr, "%i ", get(i));
246 fprintf(stderr, "\n");