Reputation: 59
I'm new to Boost Multi Index container, and was wondering if it could solve in a more effecient way my problem, simplified thus:
struct A {
int id;
}
struct B {
int id;
std::list<A> products;
}
Each A having a strictly unique ID, I want to be able with a single multi index container, be able to look for B. By B's id, and by A's Id.
At the moment i'm working with nice std::map, and map linking A ids to B ids. So to say. It works fine enough. But, I'm having other parameters for such a look up and it's getting really nasty :)
EDIT:
As per comment request I'll elaborate somewhat:
I've Satellites, which in turn have many Transponders and many Sources. I want to be able to find a Satellite for a given Transponder id or Source id( which are indeed unique )
Sadly I don't have hand on Satellite struct, means, I can't alter it.
Briefly it looks like that :
struct Satellite {
int norad_id;
std::list<Transponder> transponders;
std::list<Source> sources;
... some more data
}
What I want to do is simply search a whatever of Satellites, and find a Satellite having a specific transponder-, or source-, or norad id.
At the 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 the example @sehe provided, I see it would be somewhat easier if I were to spawn a relationnal struct. I guess I'll give it a try ... :)
Upvotes: 1
Views: 71
Reputation: 392911
In the absense of exact use cases, here' some suggestions to model the indices based on what you 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 could also get quite smart with a composite key, which is 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 a 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 all products in category 6:
for (auto& rel : boost::make_iterator_range(table.get<compound>().equal_range(6)))
std::cout << "Product " << rel.productId << " is in category " << rel.categoryId << "\n";
}
Prints:
Product 4 is in category 6
Product 5 is in category 6
Product 6 is in category 6
¹ I crystal-balled the class names into something "realistic"
Upvotes: 1