Boost logo

Boost Users :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2006-12-14 13:13:03


bert hubert ha escrito:

> Hi everybody,
>
> I have this boost::multi_index container (I'm very very happy with
> boost::multi_index!):
>
> typedef multi_index_container<
> CacheEntry,
> indexed_by <
> ordered_unique<
> composite_key<
> CacheEntry,
> member<CacheEntry,string,&CacheEntry::d_qname>,
> member<CacheEntry,uint16_t,&CacheEntry::d_qtype>
> >,
> composite_key_compare<CIStringCompare, std::less<uint16_t> >
> >,
> sequenced<>
> >
> > cache_t;
>
> For details on CacheEntry, see
> http://wiki.powerdns.com/cgi-bin/trac.fcgi/browser/trunk/pdns/pdns/recursor_cache.hh
>
> What I want to do is use a compatible key ('char *') to search only on
> d_qname.
>
> I've tried:
>
> struct string_char_comp
> {
> bool operator()(const char* x, const tuple<string,uint16_t>& )const
> {
> return false; // bogus, just compile testing
> }
>
> bool operator()(const tuple<string,uint16_t>&, const char* x )const
> {
> return false;
> }
> };
>
> Followed by:
> cache_t d_cache;
> // ...
> d_cachecache=d_cache.equal_range(qname.c_str(), string_char_comp());
>
> But this doesn't compile with famously huge template errors (I've shortened
> boost::multi_index to bi::):

[...]

> These errors make me wonder if what I want is even possible - unless I make
> my comparison function accept a composite_key_result with lots of bi
> internals in it.
>
> Joaquin?

Hello Bert,

Your approach does not work because when string_char_comp::operator()
is invoked internally, it is *not* passed a tuple, but an object of the opaque
type composite_key_result<...> (http://tinyurl.com/yznxrj ). Moreover this
composite_key_result thing is opaque in the sense that the user is not expected
to mess much with it (read the reference for further details.)

Fortunately, what you aim for can be done with a slightly different formulation:

struct string_char_comp
{
  bool operator()(const char* x, const std::string& )const
  {
    return false; // bogus, just compile testing
  }

  bool operator()(const std::string&, const char* x )const
  {
    return false;
  }
};

...

d_cachecache=d_cache.equal_range(
    boost::make_tuple(qname.c_str()), // you can omit the make_tuple wrapper in Boost
1.34
    composite_key_compare<string_char_comp>());

Note that the composite_key_compare instantiation only needs one comparison predicate,
because you're passing one-element tuples. You can also have it combined with
uint16_t's:

d_cachecache=d_cache.equal_range(
    boost::make_tuple(qname.c_str(),105), // you cannot omit make_tuple here
    composite_key_compare<string_char_comp,std::less<uint16_t> >());

Hope this helps. Thanks for using Boost.MultiIndex in such exciting ways as
you're doing in PowerDNS.

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


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