Boost logo

Boost Users :

Subject: Re: [Boost-users] What concepts/interface must the element type of multi_index_container<> support?
From: joaquin_at_[hidden]
Date: 2011-09-19 02:06:46


El 16/09/2011 19:15, Chris Cleeland escribió:
> I'm trying to use boost::multi_index_container on a type that I've
> defined. I want the container to have two indices:
>
> 1. insertion order
> 2. hashed_unique
>
> Further, I want the hash to use an sha1 hash value, which I have
> represented as a struct. So, I have something like the following:
>
> struct sha1_hash_value { ... };
>
> class MyRecord {
> public:
> ...
> sha1_hash_value hash() const { return _sha1_hash; }
> ...
> private:
> sha1_hash_value _sha1_hash;
> };
>
> using namespace boost::multi_index;
>
> typedef boost::multi_index_container<
> MyRecord,
> indexed_by<
> sequenced<>,
> hashed_unique<const_mem_fun<MyRecord,sha1_hash_value,&MyRecord::hash> >
> >
>> RecordSet;

Hi Chris, you have the concepts here slightly mixed up. The specification of a unique
hashed index goes like (http://tinyurl.com/3n67upt )

hashed_unique<
   KeyFromValue,
   Hash=boost::hash<KeyFromValue::result_type>,
   Pred=std::equal_to<KeyFromValue::result_type>
>

where KeyFromValue is a key extractor, that is, the functor returning the piece of
info on which you want to do the hashing, and Hash and Pred are the (hashing,
equality) pair on that key. Furthermore, Hash must return a std::size_t.

Your particular case is a little exotic because MyRecord stores a precalculated
hash value (usually, the hash is calculated on the fly.) You can handle this situation
in one of the following two ways:

1. Consider that the key is MyRecord::hash():

   hashed_unique<
     const_mem_fun<MyRecord,sha1_hash_value,&MyRecord::hash>
>

For this to work, the default Hash predicate (boost::hash<sha1_hash_value>)
has to be defined (hence your compiling problems), see http://tinyurl.com/5sfsmyo
for details, and the same goes for std::equal<sha1_hash_value>. Alternatively you
can provide your own Hash and Pred functors other than the default.
As the sha1_hash_value is already a hash value, probably you only need to
implement a conversion from sha1_hash_value to std::size_t.

2. Consider that the key is MyRecord

   hashed_unique<
     MyRecord
>

Here, the default value for Hash is boost::hash<MyRecord>, which again you
must customize as explained in http://tinyurl.com/5sfsmyo , simply using
the value returned by MyRecord::hash in the process. Similar considerations
apply to std::equal<MyRercord>.

Hope this helps,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo

Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo.
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at.
http://www.tid.es/ES/PAGINAS/disclaimer.aspx


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net