c++ - Boost Multi Index: index based on list content -
i'm new boost multi index container, , wondering if solve in more effecient way problem, simplified thus:
struct { int id; } struct b { int id; std::list<a> products; }
each having strictly unique id, want able single multi index container, able b. b's id, , a's id.
at moment i'm working nice std::map, , map linking ids b ids. say. works fine enough. but, i'm having other parameters such , it's getting nasty :)
edit:
as per comment request i'll elaborate somewhat:
i've satellites, in turn have many transponders , many sources. want able find satellite given transponder id or source id( indeed unique )
sadly don't have hand on satellite struct, means, can't alter it.
briefly looks :
struct satellite { int norad_id; std::list<transponder> transponders; std::list<source> sources; ... more data }
what want search whatever of satellites, , find satellite having specific transponder-, or source-, or norad id.
at moment, i'm using 3 nice maps
std::map<int /*norad*/ ,satellite> satellites; std::map<int /*transponder id*/, int/* norad */> transponder_to_satellite; std::map<int /* source_id */, int /* norad */ > source_to_satellite;
from example @sehe provided, see easier if spawn relationnal struct. guess i'll give try ... :)
in absense of exact use cases, here' suggestions model indices based on showed¹
struct product { int id; }; struct category { int id; }; struct productcategoryrelation { int productid; int categoryid; }; namespace bmi = boost::multi_index; using relationtable = bmi::multi_index_container< productcategoryrelation, bmi::indexed_by< bmi::ordered_unique< bmi::tag<struct by_product>, bmi::member<productcategoryrelation, int, &productcategoryrelation::productid> >, bmi::ordered_unique< bmi::tag<struct by_category>, bmi::member<productcategoryrelation, int, &productcategoryrelation::categoryid> > > >;
you quite smart composite key, versatile in ordered_*
indexes:
using relationtable = bmi::multi_index_container< productcategoryrelation, bmi::indexed_by< bmi::ordered_unique< bmi::tag<struct by_product>, bmi::composite_key<productcategoryrelation, bmi::member<productcategoryrelation, int, &productcategoryrelation::categoryid>, bmi::member<productcategoryrelation, int, &productcategoryrelation::productid> > > > >;
here's small demo:
#include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/mem_fun.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/hashed_index.hpp> #include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/global_fun.hpp> #include <list> struct product { int id; }; struct category { int id; }; struct productcategoryrelation { int productid; int categoryid; }; namespace bmi = boost::multi_index; using relationtable = bmi::multi_index_container< productcategoryrelation, bmi::indexed_by< bmi::ordered_unique< bmi::tag<struct compound>, bmi::composite_key<productcategoryrelation, bmi::member<productcategoryrelation, int, &productcategoryrelation::categoryid>, bmi::member<productcategoryrelation, int, &productcategoryrelation::productid> > > > >; #include <iostream> #include <boost/range/iterator_range.hpp> int main() { relationtable table { productcategoryrelation { 1, 7 }, productcategoryrelation { 2, 7 }, productcategoryrelation { 3, 7 }, productcategoryrelation { 4, 6 }, productcategoryrelation { 5, 6 }, productcategoryrelation { 6, 6 }, productcategoryrelation { 7, 5 }, productcategoryrelation { 8, 5 }, productcategoryrelation { 9, 5 }, }; // find products in category 6: (auto& rel : boost::make_iterator_range(table.get<compound>().equal_range(6))) std::cout << "product " << rel.productid << " in category " << rel.categoryid << "\n"; }
prints:
product 4 in category 6 product 5 in category 6 product 6 in category 6
¹ crystal-balled class names "realistic"
Comments
Post a Comment