Boost.MultiIndex: searching for items using multiple fields

I use the Boost multi_index container to store objects according to 2 integer keys K1 and K2. I can easily get an iterator over all elements satisfying "K1 == X", for example, taking the first index and using the find () function (idem for K2 and value Y), but I'm looking for a way to get an iterator over all elements satisfying like K1 == X and K2 == Y. The obvious solution is to get an iterator over all elements satisfying K1 == X, and then build boost :: filter_iterator with the predicate K2 == Y, but is there any way to do this (maybe more efficiently) only with Boost.MultiIndex?

thanks

Mathieu

+6
source share
1 answer

You can use boost :: multi_index :: composite_key with K1 and K2 .

Here is a small example, which is also located at ideone.com :

 #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/composite_key.hpp> #include <iostream> struct Stuff { Stuff (int iFirst, int iSecond) : m_iFirst(iFirst), m_iSecond(iSecond) { } int m_iFirst; int m_iSecond; }; std::ostream& operator<<(std::ostream& rOut, Stuff const& rStuff) { return rOut << rStuff.m_iFirst << "/" << rStuff.m_iSecond << "\n"; } struct FirstIdx{}; struct SecondIdx{}; struct BothIdx{}; typedef boost::multi_index_container< Stuff, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique<boost::multi_index::tag<FirstIdx>, boost::multi_index::member<Stuff, int, &Stuff::m_iFirst> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<SecondIdx>, boost::multi_index::member<Stuff, int, &Stuff::m_iSecond> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<BothIdx>, boost::multi_index::composite_key<Stuff, boost::multi_index::member<Stuff, int, &Stuff::m_iFirst>, boost::multi_index::member<Stuff, int, &Stuff::m_iSecond> > > > > TDicStuffs; typedef TDicStuffs::index<FirstIdx>::type TFirstIdx; typedef TDicStuffs::index<SecondIdx>::type TSecondIdx; typedef TDicStuffs::index<BothIdx>::type TBothIdx; int main(int argc, char *argv[]) { TDicStuffs stuffs; // fill some stuffs stuffs.insert(Stuff(1, 1)); stuffs.insert(Stuff(1, 2)); stuffs.insert(Stuff(1, 3)); stuffs.insert(Stuff(2, 1)); stuffs.insert(Stuff(2, 2)); stuffs.insert(Stuff(2, 3)); stuffs.insert(Stuff(3, 1)); stuffs.insert(Stuff(3, 2)); stuffs.insert(Stuff(3, 3)); assert(stuffs.size() == 9); // search for m_iFirst == 2 TFirstIdx::const_iterator itFirstLower; TFirstIdx::const_iterator itFirstUpper; boost::tie(itFirstLower, itFirstUpper) = stuffs.get<FirstIdx>().equal_range(2); assert(std::distance(itFirstLower, itFirstUpper) == 3); std::copy(itFirstLower, itFirstUpper, std::ostream_iterator<Stuff>(std::cout << "\n")); // search for m_iSecond == 3 TSecondIdx::const_iterator itSecondLower; TSecondIdx::const_iterator itSecondUpper; boost::tie(itSecondLower, itSecondUpper) = stuffs.get<SecondIdx>().equal_range(3); assert(std::distance(itSecondLower, itSecondUpper) == 3); std::copy(itSecondLower, itSecondUpper, std::ostream_iterator<Stuff>(std::cout << "\n")); // search for m_iFirst == 2 m_iSecond == 3 TBothIdx::const_iterator itBothLower; TBothIdx::const_iterator itBothUpper; boost::tie(itBothLower, itBothUpper) = stuffs.get<BothIdx>().equal_range(boost::make_tuple(2,3)); assert(std::distance(itBothLower, itBothUpper) == 1); std::copy(itBothLower, itBothUpper, std::ostream_iterator<Stuff>(std::cout << "\n")); return 0; } 
+6
source

Source: https://habr.com/ru/post/900719/


All Articles