Je recherche la solution optimale pour extraire des objets basés sur des bits de base à partir d'un conteneur multi-index. Pour simplifier, les données sont:Recherche de données de champ binaire dans un conteneur multi-index Boost
enum Bit
{
b0 = 1,
b1 = 2,
b2 = 4
};
struct Item
{
int field; // contains Bit values
int info;
};
Pour autant que je sais qu'il pourrait y avoir 2 possibilités:
Utilisez un prédicat personnalisé dans l'appel de equal_range (Cet exemple ne fonctionne pas parce que je ne savoir comment définir le prédicat):
struct MyTag; using boost::multi_index_container; using namespace boost::multi_index; typedef composite_key<Item, member<Item, int, &Item::field>, member<Item, int, &Item::info> > CompositeKey; typedef hashed_non_unique< tag<MyTag>, CompositeKey> Index1; typedef boost::multi_index_container<Item, indexed_by<Index1> > Container; struct Predicate: public Index1::pred_type { /// what to put here? }; void f() { Item item1 = { int(b0 | b1), 123}; Item item2 = { int(b1 | b2), 123}; Item item3 = { int(b2), 123}; Container c; c.insert(item1); c.insert(item2); c.insert(item3); auto result = c.get<MyTag>().equal_range(boost::make_tuple(int(b2), 123), Index1::hash_type(), Predicate()); for(auto i = result.first; i != result.second; ++i) { std::cout << i->field << ' '; // expect item2 and item3 } }
Ajouter accesseurs dans l'article et les index dans le conteneur multi-index pour chaque bit de l'énumération:
struct Item { int field; int info; bool isB0() const { return (field & b0) != 0; } bool isB1() const { return (field & b1) != 0; } bool isB2() const { return (field & b2) != 0; } }; struct MyTag1; struct MyTag2; struct MyTag3; using boost::multi_index_container; using namespace boost::multi_index; typedef composite_key<Item, const_mem_fun<Item, bool, &Item::isB0>, member<Item, int, &Item::info> > CompositeKeyB0; typedef composite_key<Item, const_mem_fun<Item, bool, &Item::isB1>, member<Item, int, &Item::info> > CompositeKeyB1; typedef composite_key<Item, const_mem_fun<Item, bool, &Item::isB2>, member<Item, int, &Item::info> > CompositeKeyB2; typedef hashed_non_unique< tag<MyTag1>, CompositeKeyB0> Index1; typedef hashed_non_unique< tag<MyTag2>, CompositeKeyB1> Index2; typedef hashed_non_unique< tag<MyTag3>, CompositeKeyB2> Index3; typedef boost::multi_index_container<Item, indexed_by<Index1, Index2, Index3> > Container; void f() { Item item1 = { int(b0 | b1), 123}; Item item2 = { int(b1 | b2), 123}; Item item3 = { int(b2), 123}; Container c; c.insert(item1); c.insert(item2); c.insert(item3); auto result = c.get<MyTag2>().equal_range(boost::make_tuple(true, 123)); for(auto i = result.first; i != result.second; ++i) { std::cout << i->field << ' '; // expect item2 and item3 } }
Quels sont les critères de sélection précis? est-ce que la recherche de 0b0010 correspond à la valeur de clé 0b0011? –
(item.field & Bit :: bx)! = 0. Oui. – Flaviu
auquel cas l'option 1 n'est pas une possibilité. –