Boost logo

Boost Users :

Subject: Re: [Boost-users] multi_index_comtainer questions
From: Andrew Holden (aholden_at_[hidden])
Date: 2009-10-16 10:28:48


Vladimir Voronkov wrote on Thursday, October 15, 2009 10:20 AM:
> Hi again,
>
> Thanks for the answers, they helped my. Now I have come with some another probably stupid questions.
>
> I've changed the initial example by adding some attribute to the element. Let's say int.
>
> typedef std::string UserInfo;
> typedef std::less<std::string> UserInfoLess;
>
> typedef boost::multi_index_container<
> std::pair<UserInfo, int>,
> boost::multi_index::indexed_by<
> boost::multi_index::sequenced<>,
> boost::multi_index::ordered_unique<
> boost::multi_index::member<std::pair<UserInfo, int>, UserInfo, &std::pair<UserInfo, int>::first>,
> UserInfoLess>,
> boost::multi_index::ordered_non_unique<
> boost::multi_index::member<std::pair<UserInfo, int>, int, &std::pair<UserInfo, int>::second> >
> >
> UsersContainer;
>
>typedef UsersContainer::nth_index<2>::type UsersSelected;
>
> This flag has not many possible values and most probably there will be many pairs in the container with the > same value of this flag. Now I want to enumerate all values in the container with some specific value of this flag. There are many ways to do that.
>
> 1. Use lower_bound for getting iterator for the UsersSelected index.
> 2. implement own iterator that use some int value as a parameter.
>
> But the ideal solution would be to expose some kind of "view" of the container that behaves like list, so we > could use it's iterator from begin() to end() taking only necessary elements.

I have found this to be a very common use case for multi-index containers. I normally use ordered indices and composite keys to do this. Specifically, I would recommend the following index:

boost::multi_index::ordered_unique //ordered_non_unique will also work
<
        boost::multi_index::composite_key
        <
                std::pair<UserInfo, int>,
                boost::multi_index::member<std::pair<UserInfo, int>, int, &std::pair<UserInfo, int>::second>,
                boost::multi_index::member<std::pair<UserInfo, int>, UserInfo, &std::pair<UserInfo, int>::first>
>
>

typedef UsersContainer::nth_index<2>::type::iterator UsersByFlagIterator;


You can now get a sorted list of all users with a certain flag using:

std::pair<UsersByFlagIterator, UsersByFlagIterator> range = my_container::get<2>().equal_range(boost::make_tuple(desired_flag));


This index can also find a specific flag, name combination like this:

UsersByFlagIterator entry = my_container::get<2>().find(boost::make_tuple(desired_flag, desired_name));


> -----Original Message-----
> From: boost-users-bounces_at_[hidden] [mailto:boost-users-
> bounces_at_[hidden]] On Behalf Of Joaquin M Lopez Munoz
> Sent: Tuesday, October 13, 2009 8:16 PM
> To: boost-users_at_[hidden]
> Subject: Re: [Boost-users] multi_index_comtainer questions
>
> Andrew Holden <aholden <at> charteroaksystems.com> writes:
>
> >
> > On Tuesday, October 13, 2009 9:53 AM, Vladimir Voronkov wrote:
> > > Do iterators keep the property of set’s
> > > iterators that they remain valid after insertion of an element?
> > [...]
> >
> > As far as I know, all iterators to all indices of a multi-index
> > remain valid unless they point to a deleted element.
>
> This is correct.
>
> Joaquín M López Muñoz
> Telefónica, Investigación y Desarrollo
>
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
Boost-users_at_[hidden]
http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net