Re: boost multi index - possible?
On 12 nov, 09:44, "suresh.amritapuri" <suresh.amritap...@gmail.com>
wrote:
Hi,
I have a map of a set of strings and a double.
map<set<string>,double>
Typical entries are like this:
(a1,b1,c1) -> 10 ;
(a1,b1,c2)->2.5
(a1,b1,c2)-> 3
Of course if i give full set as the key, i can get the value. But if
i want all entries containing say a1, how to do it? Is it possible to
do this through boost::multi-index? I am unable to make out by reading
multi-index doc. Is there any other way than boost multi-index?
Hi, you can do this with Boost.MultiIndex using the so-called
special lookup operations:
http://www.boost.org/libs/multi_index/doc/tutorial/basics.html#special_lookup
Please find below a complete example showing the technique for your
particular scenario. You'll probably have some difficulties grasping
the code, do not hesitate to ask away. For simplicity's sake, some of
the bits below are not optimal (vg. partial_key_compare::operator()
could be implemented without using boost::next).
Joaqu?n M L?pez Mu?oz
Telef?nica, Investigaci?n y Desarrollo
#include <algorithm>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/utility.hpp>
#include <iostream>
#include <iterator>
#include <set>
#include <string>
using namespace boost::multi_index;
using namespace std;
typedef set<string> key_type;
struct element
{
element(const key_type& key,double value):key(key),value(value){}
key_type key;
double value;
};
ostream& operator<<(ostream& os,const element& e)
{
copy(e.key.begin(),e.key.end(),ostream_iterator<string>(os," "));
os<<"-->"<<e.value;
return os;
}
class partial_key
{
public:
partial_key(const key_type& k):pk(&k){}
const key_type& get()const{return *pk;}
private:
const key_type *pk;
};
struct partial_key_compare
{
bool operator()(const partial_key& pk,key_type& k)const
{
return lexicographical_compare(
pk.get().begin(),pk.get().end(),
k.begin(),boost::next(k.begin(),min(pk.get().size(),k.size())));
}
bool operator()(key_type& k,const partial_key& pk)const
{
return lexicographical_compare(
k.begin(),boost::next(k.begin(),min(pk.get().size(),k.size())),
pk.get().begin(),pk.get().end());
}
};
typedef multi_index_container<
element,
indexed_by<
ordered_non_unique<member<element,key_type,&element::key> >
>
container;
key_type make_key(const char *s1)
{
key_type k;k.insert(s1);return k;
}
key_type make_key(const char *s1,const char *s2)
{
key_type k;k.insert(s1);k.insert(s2);return k;
}
key_type make_key(const char *s1,const char *s2,const char *s3)
{
key_type k;k.insert(s1);k.insert(s2);k.insert(s3);return k;
}
void dump(container::iterator first,container::iterator last)
{
std::copy(first,last,ostream_iterator<element>(cout,"\n"));
}
void dump(const pair<container::iterator,container::iterator> p)
{
dump(p.first,p.second);
}
int main()
{
container c;
c.insert(element(make_key("a1","b1","c1"),10.0));
c.insert(element(make_key("a1","b1","c2"),2.5));
c.insert(element(make_key("a1","b1","c2"),3.0));
c.insert(element(make_key("a1","b2","c1"),5.6));
c.insert(element(make_key("a2","b1","c1"),1.0));
cout<<"contents:\n";
dump(c.begin(),c.end());
cout<<"keys beginning with \"a1\":\n";
dump(c.equal_range(partial_key(make_key("a1")),partial_key_compare
()));
cout<<"keys beginning with \"a1\",\"b1\":\n";
dump(c.equal_range(partial_key(make_key
("a1","b1")),partial_key_compare()));
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]