Commit 463c97dd authored by Etienne Baratte's avatar Etienne Baratte

pack vector<bool> on uint64_t instead of uint8_t

parent cd85d1d6
...@@ -228,36 +228,61 @@ public: ...@@ -228,36 +228,61 @@ public:
// Special case to avoid using 1 byte per bool // Special case to avoid using 1 byte per bool
error apply(std::vector<bool>& x) { error apply(std::vector<bool>& x) {
uint64_t len = x.size(); // Convert vector<bool> to a vector<uint64>,
auto err = begin_sequence(len); // by packing each block of 64 booleans on a 64-bits integer.
if (err || len == 0) // To not waste up to 63 bits, the last uint64_t
// (ie. the last 'remainder' booleans) is encoded as a var-int
auto remainder = static_cast<uint8_t>(x.size() % 64);
auto err = apply_builtin(u8_v, &remainder);
if (err)
return err; return err;
struct { struct {
size_t len; void operator()(std::vector<bool>& lhs, std::vector<uint64_t>& rhs) const {
void operator()(std::vector<bool>& lhs, std::vector<uint8_t>& rhs) const { lhs.resize(rhs.size() * 64, false);
lhs.resize(len, false);
size_t cpt = 0; size_t cpt = 0;
for (auto v: rhs) { for (auto v: rhs) {
for (int k = 0; k < 8; ++k) { for (int k = 0; k < 64; ++k) {
lhs[cpt] = ((v & (1 << k)) != 0); lhs[cpt++] = ((v & (1ul << k)) != 0);
if (++cpt >= len)
return;
} }
} }
} }
void operator()(std::vector<uint8_t>& lhs, std::vector<bool>& rhs) const { void operator()(std::vector<uint64_t>& lhs, std::vector<bool>& rhs) const {
size_t k = 0; if (rhs.empty())
lhs.resize((rhs.size() - 1) / 8 + 1, 0); return;
for (bool b: rhs) { size_t len = rhs.size() - rhs.size() % 64;
lhs.resize(len / 64, 0);
for (size_t k = 0; k < len; ++k) {
auto b = rhs[k];
if (b) if (b)
lhs[k / 8] |= (1 << (k % 8)); lhs[k / 64] |= (1ul << (k % 64));
++k;
} }
} }
} assign; } assign;
assign.len = len; std::vector<uint64_t> tmp;
std::vector<uint8_t> tmp; err = convert_apply(dref(), x, tmp, assign);
return convert_apply(dref(), x, tmp, assign); if (err || !remainder)
return err;
// the last uint64_t for 'remainder' bits
if (Derived::reads_state) {
uint64_t encoded = 0;
auto len = x.size();
for (int k = 0; k < remainder; ++k) {
auto b = x[len - remainder + k];
if (b)
encoded |= (1ul << k);
}
return begin_sequence(encoded);
} else {
uint64_t encoded = 0;
err = begin_sequence(encoded);
if (err)
return err;
x.reserve(x.size() + remainder);
for (int k = 0; k < remainder; ++k) {
x.push_back((bool) (encoded & (1ul << k)));
}
return none;
}
} }
template <class T> template <class T>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment