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:

live on coliru

#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

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -