diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index c7c551c2b..d235dae41 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -31,6 +31,10 @@ namespace dev { +/// Compile-time calculation of Log2 of constant values. +template struct StaticLog2 { enum { result = 1 + StaticLog2::result }; }; +template <> struct StaticLog2<1> { enum { result = 0 }; }; + extern std::random_device s_fixedHashEngine; /// Fixed-size raw-byte array container type, with an API optimised for storing hashes. @@ -171,18 +175,21 @@ public: template inline FixedHash bloomPart() const { - static_assert((M & (M - 1)) == 0, "M must be power-of-two"); - static const unsigned c_bloomBits = M * 8; - unsigned mask = c_bloomBits - 1; - unsigned bloomBytes = (dev::toLog2(c_bloomBits) + 7) / 8; + unsigned const c_bloomBits = M * 8; + unsigned const c_mask = c_bloomBits - 1; + unsigned const c_bloomBytes = (StaticLog2::result + 7) / 8; + + static_assert((M & (M - 1)) == 0, "M must be power-of-two"); + static_assert(P * c_bloomBytes <= N, "out of range"); + FixedHash ret; byte const* p = data(); for (unsigned i = 0; i < P; ++i) { unsigned index = 0; - for (unsigned j = 0; j < bloomBytes; ++j, ++p) + for (unsigned j = 0; j < c_bloomBytes; ++j, ++p) index = (index << 8) | *p; - index &= mask; + index &= c_mask; ret[M - 1 - index / 8] |= (1 << (index % 8)); } return ret;