Re: [Boost-users] [multi_index] Sorting object based on some specified criteria !!

Hi Joaquin,
First of all thanks for your time and response. I have it working as follows, but seems I have to recalculate iterators if in case I later on modify group associated with that access point. Is there any way that iterators will know automatically update when I update access point in future to some other group?
Let me know if you have come across that one. I am going to look in your code in detail and get back to you in case of any questions.
Thanks
Priyank
// class Access point test
class Access_Point {
public:
Access_Point(int id, int paging_group):id_(id), pg_(paging_group) {
}
bool by_id(int _id) const {
return (_id == id_);
}
int paging_group(int _pg) const {
return (_pg == pg_);
}
int id() const {
return id_;
}
int pg() const {
return pg_;
}
int pg(int _pg) {
pg_ = _pg;
}
friend ostream& operator << (ostream& _os, const Access_Point& _ap);
private:
int id_;
int pg_;
};
ostream& operator << (ostream& _os, const Access_Point& _ap)
{
_os << "Id: " << _ap.id_ << "Pg: " << _ap.pg_ << endl;
return _os;
}
// tag ids
struct hashed_objs {
};
struct paging_group {
};
// Create multi index container
typedef multi_index_container<
Access_Point*,
indexed_by<
hashed_unique<
tag
Access_Points;
int ACE_MAIN (int, ACE_TCHAR *[])
{
// ACCESS POINT CHECK
Access_Points pool;
Access_Point * a1 = new Access_Point(1, 1);
Access_Point * a2 = new Access_Point(2, 1);
Access_Point * a3 = new Access_Point(3, 2);
Access_Point * a4 = new Access_Point(4, 1);
// insert all the access points
pool.insert(a1);
pool.insert(a2);
pool.insert(a3);
// get iterator
index_iterator
Hi all,
I have following kind of class and having some identifier and group id associated with particular procedure. I want to know if I have to get the procedures relating particular
group for ex. (groupId == 1). How do I do using multiindex container? Can somebody please give me some hint or code if they have done something similar to what I want to do?
Hello Priyank, I'm not sure I've understood what you're after, but let me try anyway:
As you'll search for group, you'll need an additional index (the one you've set up is based on process ID). The following has not been compiled, beware typos:
struct id {};
struct group {};
typedef
multi_index_container<
Procedure*,
indexed_by<
hashed_unique<
tag<id>,
const_mem_fun
Procedure_Hashed_Pool; typedef Procedure_Hashed_Pool:: index<id>::type Procedure_By_Id; typedef Procedure_Hashed_Pool:: index<group>::type Procedure_By_Group; (I've decided to make the new index hashed non-unique, you could also have it ordered non-unique if you need the elements to be sorted by group ID --hashing only guarantees fast retrieval.) And now you can simply use equal_range() on this index to do what you want: int gr=...; const Procedure_By_Group& procedure_bg= procedure_pool.get<group>(); std::pair< Procedure_By_Group::iterator, Procedure_By_Group::iterator
p=procedure_bg.equal_range(gr);
p will hold the range of elements with group ID == gr. Is this what you were after? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Patel Priyank-PPATEL1 ha escrito:
Hi Joaquin,
First of all thanks for your time and response. I have it working as follows, but seems I have to recalculate iterators if in case I later on modify group associated with that access point. Is there any way that iterators will know automatically update when I update access point in future to some other group? Let me know if you have come across that one. I am going to look in your code in detail and get back to you in case of any questions.
Hello Priyank, there's an issue in your code:
// change paging group from access point 4 a4->pg(2);
This is incorrect and can lead to hard-to-detect failures later on during the execution of the program: basically, you're changing an element key "under the table", that is, without the multi-index container having a chance to notice, which directly breaks the internal invariants the container relies on. Under usual conditions it is difficult to change a key in such a way, because the elements of a multi-index container are treated as const, but here you can easily get by because it is pointers that you are storing. The proper way to modify an element is by using replace, modify of modify_key, as explained in http://boost.org/libs/multi_index/doc/tutorial.html#ord_updating In your case, instead of what you've got you could write the following: // get an iterator to a4. You could also have stored those iterators in the // first place when inserting the elements. Access_Points::iterator it=pool.find(4); // change paging group from access point 4 pool.modify(it,boost::bind(&Access_point::pg,_1,2)); By using modify(), the multi-index container is on control of the updating operation, and will rearrange a4 according to its new paging group.
// NEED TO RECALCULATE ITERATORS boost::tuples::tie(pg0, pg1) = get
(pool).equal_range(1);
As for your original question, yes, you've got to recalculate these iterators in the general case, as elements might have been moved around, inserted or deleted: for instance, if the element originally pointed to by pg0 had been deleted, pg0 would not even be valid after that. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
Joaquín Mª López Muñoz
-
Patel Priyank-PPATEL1