[MultiIndex] is it possible to create multi-key key-extractors?
Hi,
For the following struct:
struct Flower
{
int type;
string name;
std::list<string> aliases;
};
I want to create a multiindexed container that indexes Flower objects by
type, name, and aliases, where aliases is some iteratable collection of
strings. I just don't know if it's possible to create a multi-key
key-extractor for aliases. So far I've come up with the following:
typedef boost::multi_index_container<
Flower,
indexed_by<
ordered_unique<
member
FlowerMngr;
Thanks, -Mostafa
Mostafa
struct Flower { int type; string name; std::list<string> aliases; };
I want to create a multiindexed container that indexes Flower objects by type, name, and aliases, where aliases is some iteratable collection of strings. [snip]
You probably want to read up on MultiIndex's Key_Extractor concept and some of the realizations besides "member". Specifically the "global_fun" may be helpful: http://tinyurl.com/2cumme4 HTH, -Ryan
On Sun, 08 Aug 2010 13:12:17 -0700, Ryan Gallagher
Mostafa
writes: struct Flower { int type; string name; std::list<string> aliases; };
I want to create a multiindexed container that indexes Flower objects by type, name, and aliases, where aliases is some iteratable collection of strings. [snip]
You probably want to read up on MultiIndex's Key_Extractor concept and some of the realizations besides "member". Specifically the "global_fun" may be helpful: http://tinyurl.com/2cumme4
Thanks. I should have clarified in my earlier posting that this question was posed after reading the documentation on key-extractors. More precisely, I'm looking for a keyS extractor. I am/was hoping something of this nature is constructible from what is already in the MultiIndex library. -Mostafa
Follow up ...
More precisely, I am wondering if it's possible to create a keyS-extractor
for a multi-index container.
As a further example, let's say that in addition to the above posting, I
have:
struct Nursery
{
std::list
AMDG Mostafa wrote:
For the following struct:
struct Flower { int type; string name; std::list<string> aliases; };
I want to create a multiindexed container that indexes Flower objects by type, name, and aliases, where aliases is some iteratable collection of strings. I just don't know if it's possible to create a multi-key key-extractor for aliases. So far I've come up with the following:
I assume that you want to be able to look up the Flower from a string, which should be one of the aliases? You can't do this with multi-index. A single object corresponds to a single key. In Christ, Steven Watanabe
On Sun, 08 Aug 2010 17:29:49 -0700, Steven Watanabe
AMDG
Mostafa wrote:
For the following struct:
struct Flower { int type; string name; std::list<string> aliases; };
I want to create a multiindexed container that indexes Flower objects by type, name, and aliases, where aliases is some iteratable collection of strings. I just don't know if it's possible to create a multi-key key-extractor for aliases. So far I've come up with the following:
I assume that you want to be able to look up the Flower from a string, which should be one of the aliases? You can't do this with multi-index.
Yes.
A single object corresponds to a single key.
That's pretty much what I figured from the documentation, I was just
hoping for some kind of workaround that I might have missed.
Well, here goes a feature request ... (A rough outline.)
I propose adding a key-extractorS concept to the multi-index library.
Something along the lines of the existing key-extractor concept, modified
such that
key_extractorS::result_type is a Boost.Range of keys
and providing adaptor classes for creating such a Range from
multi_index::value_type member variables, methods ..., (basically a
key-extractorS counterpart for the equivalent existing key-extractors,
where approriate of course).
The motivation for this request is that a multi-index element can be
indexed by a collection of values associated with that element.
As an example: (rehashing from previous posts)
struct Flower
{
int getType() const;
string name;
std::list<string> aliases;
};
struct Nursery
{
std::list
AMDG Mostafa wrote:
That's pretty much what I figured from the documentation, I was just hoping for some kind of workaround that I might have missed.
Well, here goes a feature request ... (A rough outline.)
I propose adding a key-extractorS concept to the multi-index library. Something along the lines of the existing key-extractor concept, modified such that
key_extractorS::result_type is a Boost.Range of keys
Sorry, but I don't think that this can be implemented in a way that is consistent with the rest of the library. You'd be better off using an auxillary map of pointers. No implementation that I can think of is going to be more efficient than that, anyway. In Christ, Steven Watanabe
Steven Watanabe escribió:
AMDG
Mostafa wrote:
That's pretty much what I figured from the documentation, I was just hoping for some kind of workaround that I might have missed.
Well, here goes a feature request ... (A rough outline.)
I propose adding a key-extractorS concept to the multi-index library. Something along the lines of the existing key-extractor concept, modified such that
key_extractorS::result_type is a Boost.Range of keys
Sorry, but I don't think that this can be implemented in a way that is consistent with the rest of the library. You'd be better off using an auxillary map of pointers. No implementation that I can think of is going to be more efficient than that, anyway.
Adding to Steven's answer, you'll need to somehow maintain additional data
structures to do what you want. As each element has one and only one key
per (key-based) index, you need an extra level of indirection that maps
all the aliases into a single value that can act as the key. A possible
way to
do this is by using a "multi-key bag" (for want of a better name) that you
can feed with lists of keys to obtain a representative token of the list in
return (a N-to-1 bimap, really). Something like this:
template<typename Key>
class multi_key_bag
{
public:
typedef Key key_type;
typedef std::size_t token_type;
static const token_type not_found=static_cast
container; container cont; token_type next_token; };
#include
FlowerMngr;
int main() { FlowerMultiKeyExtractor::MultiKeyBag bag; FlowerMultiKeyExtractor ext((bag)); FlowerMngr mgr( FlowerMngr::ctor_args_list(boost::make_tuple(ext))); Flower f0; f0.aliases=list_of("rose")("alba")("gallica"); bag.insert(f0.aliases.begin(),f0.aliases.end()); mgr.insert(f0); Flower f1; f1.aliases=list_of("narcissus")("daffodil")("jonquil"); bag.insert(f1.aliases.begin(),f1.aliases.end()); mgr.insert(f1); assert(*(mgr.find(bag.find("rose"))->aliases.begin())=="rose"); assert(*(mgr.find(bag.find("alba"))->aliases.begin())=="rose"); assert(*(mgr.find(bag.find("jonquil"))->aliases.begin())=="narcissus"); assert(bag.find("daisy")==FlowerMultiKeyExtractor::MultiKeyBag::not_found); mgr.erase(bag.find("jonquil")); bag.erase("jonquil"); assert(bag.find("narcissus")==FlowerMultiKeyExtractor::MultiKeyBag::not_found); }
participants (4)
-
joaquin@tid.es
-
Mostafa
-
Ryan Gallagher
-
Steven Watanabe