Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unordered (hash) map from bitset to bitset on boost

I want to use a cache, implemented by boost's unordered_map, from a dynamic_bitset to a dynamic_bitset. The problem, of course, is that there is no default hash function from the bitset. It doesn't seem to be like a conceptual problem, but I don't know how to work out the technicalities. How should I do that?

like image 341
R S Avatar asked Oct 09 '10 16:10

R S


3 Answers

I found an unexpected solution. It turns out boost has an option to #define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS. When this is defined, private members including m_bits become public (I think it's there to deal with old compilers or something).

So now I can use @KennyTM's answer, changed a bit:

namespace boost {
    template <typename B, typename A>
    std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {            
        return boost::hash_value(bs.m_bits);
    }
}
like image 178
R S Avatar answered Oct 08 '22 03:10

R S


There's to_block_range function that copies out the words that the bitset consists of into some buffer. To avoid actual copying, you could define your own "output iterator" that just processes individual words and computes hash from them. Re. how to compute hash: see e.g. the FNV hash function.

Unfortunately, the design of dynamic_bitset is IMHO, braindead because it does not give you direct access to the underlying buffer (not even as const).

like image 43
zvrba Avatar answered Oct 08 '22 04:10

zvrba


It is a feature request.

One could implement a not-so-efficient unique hash by converting the bitset to a vector temporary:

namespace boost {
    template <typename B, typename A>
    std::size_t hash_value(const boost::dynamic_bitset<B, A>& bs) {
        std::vector<B, A> v;
        boost::to_block_range(bs, std::back_inserter(v));
        return boost::hash_value(v);
    }
}
like image 29
kennytm Avatar answered Oct 08 '22 04:10

kennytm