aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/salticidae/ref.h1
-rw-r--r--include/salticidae/stream.h66
-rw-r--r--include/salticidae/type.h17
3 files changed, 65 insertions, 19 deletions
diff --git a/include/salticidae/ref.h b/include/salticidae/ref.h
index c0b77a3..7239402 100644
--- a/include/salticidae/ref.h
+++ b/include/salticidae/ref.h
@@ -131,6 +131,7 @@ class BoxObj<T[], D>: public _BoxObj<T, D> {
BoxObj(BoxObj<T_[]> &&other): base_t(std::move(other)) {}
T &operator[](size_t idx) { return base_t::obj[idx]; }
+ const T &operator[] (size_t idx) const { return base_t::obj[idx]; }
};
template<typename T, typename D = default_delete<T>, typename T_, typename D_>
diff --git a/include/salticidae/stream.h b/include/salticidae/stream.h
index b5e0757..5b7e936 100644
--- a/include/salticidae/stream.h
+++ b/include/salticidae/stream.h
@@ -271,36 +271,36 @@ class Blob {
};
template<typename T = uint64_t>
-class Bits {
+class _Bits {
using _impl_type = T;
- static const size_t bit_per_datum = sizeof(_impl_type) * 8;
+ static const uint32_t bit_per_datum = sizeof(_impl_type) * 8;
+ static const uint32_t shift_per_datum = log2<bit_per_datum>::value;
BoxObj<_impl_type[]> data;
- size_t nbits;
- size_t ndata;
+ uint32_t nbits;
+ uint32_t ndata;
public:
- Bits(): data(nullptr) {}
- Bits(const bytearray_t &arr) {
+ _Bits(): data(nullptr) {}
+ _Bits(const bytearray_t &arr) {
load(&*arr.begin(), arr.size());
}
- Bits(const uint8_t *arr, size_t len) { load(arr, len); }
- Bits(size_t nbits): nbits(nbits) {
+ _Bits(const uint8_t *arr, uint32_t len) { load(arr, len); }
+ _Bits(uint32_t nbits): nbits(nbits) {
ndata = (nbits + bit_per_datum - 1) / bit_per_datum;
data = new _impl_type[ndata];
}
- ~Bits() {}
+ ~_Bits() {}
- void load(const uint8_t *arr, size_t len) {
+ void load(const uint8_t *arr, uint32_t len) {
nbits = len * 8;
- ndata = (len + sizeof(_impl_type) - 1) /
- sizeof(_impl_type);
+ ndata = (nbits + bit_per_datum - 1) / bit_per_datum;
data = new _impl_type[ndata];
uint8_t *end = arr + len;
- for (_impl_type *ptr = data; ptr < data + ndata;)
+ for (_impl_type *ptr = data.get(); ptr < data.get() + ndata;)
{
_impl_type x = 0;
for (unsigned j = 0, k = 0; j < sizeof(_impl_type); j++, k += 8)
@@ -317,24 +317,24 @@ class Bits {
s << htole(nbits);
if (data)
{
- for (const _impl_type *ptr = data; ptr < data + ndata; ptr++)
+ for (const _impl_type *ptr = data.get(); ptr < data.get() + ndata; ptr++)
s << htole(*ptr);
}
else
{
- for (const _impl_type *ptr = data; ptr < data + ndata; ptr++)
+ for (const _impl_type *ptr = data.get(); ptr < data.get() + ndata; ptr++)
s << htole((_impl_type)0);
}
}
void unserialize(DataStream &s) {
- _impl_type x;
- s >> x;
- nbits = letoh(x);
+ s >> nbits;
+ nbits = letoh(nbits);
ndata = (nbits + bit_per_datum - 1) / bit_per_datum;
data = new _impl_type[ndata];
- for (_impl_type *ptr = data; ptr < data + ndata; ptr++)
+ for (_impl_type *ptr = data.get(); ptr < data.get() + ndata; ptr++)
{
+ _impl_type x;
s >> x;
*ptr = letoh(x);
}
@@ -345,8 +345,36 @@ class Bits {
s << *this;
return std::move(s);
}
+
+ uint8_t get(uint32_t idx) const {
+ return (data[idx >> shift_per_datum] >>
+ (idx & (bit_per_datum - 1))) & 1;
+ }
+
+ void set(uint32_t idx) {
+ auto i = idx >> shift_per_datum;
+ auto pos = idx & (bit_per_datum - 1);
+ data[i] ^= ((data[i] >> pos) ^ 1) << pos;
+ }
+
+ void unset(uint32_t idx) {
+ auto i = idx >> shift_per_datum;
+ auto pos = idx & (bit_per_datum - 1);
+ data[i] ^= (data[i] >> pos) << pos;
+ }
+
+ void flip(uint32_t idx) {
+ auto i = idx >> shift_per_datum;
+ auto pos = idx & (bit_per_datum - 1);
+ data[i] ^= ((_impl_type)1) << pos;
+ }
+
+ uint8_t operator[](uint32_t idx) const { return get(idx); }
+
+ uint32_t size() const { return nbits; }
};
+using Bits = _Bits<>;
const size_t ENT_HASH_LENGTH = 256 / 8;
diff --git a/include/salticidae/type.h b/include/salticidae/type.h
index d5834a5..13975a5 100644
--- a/include/salticidae/type.h
+++ b/include/salticidae/type.h
@@ -65,6 +65,23 @@ struct is_ranged<T,
void_t<decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>> : std::true_type {};
+template<size_t N>
+struct log2 {
+ enum {
+ value = 1 + log2<N / 2>::value
+ };
+};
+
+template<>
+struct log2<0> {
+ enum { value = 0 };
+};
+
+template<>
+struct log2<1> {
+ enum { value = 0 };
+};
+
}
#endif