[multi_index] doing insert() within iteration over equal_range() result?

Hi all, i have the following problem: i use multi_index like this std::pairPlugins::pEvents::index::type::iterator,Plugins::pEvents::index::type::itera... range; range = this->events.get().equal_range(boost::make_tuple(event,condition)); while(range.first!=range.second){ // CALL an event handler! this->callEventHandler(range.first); // << this shows just how it works, its not exactly my code ++range.first; } within the callEventHandler and its called functions its possible that the event handler wants to register new events which results to this: this->events.insert(eventdata); The problem is OR can be, that the insert modifies the indices which modify the range.first iterators and thus a ++range.first results in an invalid "next" element this makes sense and i think most of you know this and had this problem already Questions: Does anyone have a good idea/solution how to solve this situation correctly so that the range i received will be valid? i thought about using a second multi_index which holds the newly inserted events and after the WHILE it gets moved to the original events index, but this solution only moves the problem from one index to the second which helps a bit but doesnt really solve the problem, since i could miss newly inserted events another solution i thought of is like this range = ....equal_range(...) ; while( range.first!=range.second ){ Plugins::Event &ev = (Plugins::Event&)*range.first; // get first event if(ev.alreadycalled == false){ ev.alreadycalled = true; // this element doesnt have an index and so it shouldnt invalidate the iterator/index (right?) callEventHandler(); range= ...equal_range() ; // reinitialize the range and begin to search again! } else{ ++range.first; } } but the above solution gets slower the more events are available thx all _________________________________________________________________ Explore the seven wonders of the world http://search.msn.com/results.aspx?q=7+wonders+world&mkt=en-US&form=QBRE

Prometheus Prometheus escribió:
Hi all,
i have the following problem: i use multi_index like this std::pairPlugins::pEvents::index::type::iterator,Plugins::pEvents::index::type::itera... range; range = this->events.get().equal_range(boost::make_tuple(event,condition)); while(range.first!=range.second){ // CALL an event handler! this->callEventHandler(range.first); // << this shows just how it works, its not exactly my code ++range.first; }
within the callEventHandler and its called functions its possible that the event handler wants to register new events which results to this: this->events.insert(eventdata);
The problem is OR can be, that the insert modifies the indices which modify the range.first iterators and thus a ++range.first results in an invalid "next" element this makes sense and i think most of you know this and had this problem already
Questions: Does anyone have a good idea/solution how to solve this situation correctly so that the range i received will be valid?
I think the easiest solution is to save copies of the iterators in range
before you
start the loop:
range = this->events.get().equal_range(boost::make_tuple(event,condition));
std::vectorPlugins::pEvents::index::type::iterator buff;
while(range.first!=range.second)buff.push_back(range.first++);
for(std::size_t n=0,s=buff.size();ncallEventHandler(buff[n]);
}
HTH,
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo

Date: Thu, 23 Oct 2008 16:50:15 +0200 From: joaquin@tid.es To: boost-users@lists.boost.org Subject: Re: [Boost-users] [multi_index] doing insert() within iteration over equal_range() result?
Prometheus Prometheus escribió:
Hi all,
i have the following problem: i use multi_index like this std::pair range; range = this->events.get().equal_range(boost::make_tuple(event,condition)); while(range.first!=range.second){ // CALL an event handler! this->callEventHandler(range.first); // << this shows just how it works, its not exactly my code ++range.first; }
within the callEventHandler and its called functions its possible that the event handler wants to register new events which results to this: this->events.insert(eventdata);
The problem is OR can be, that the insert modifies the indices which modify the range.first iterators and thus a ++range.first results in an invalid "next" element this makes sense and i think most of you know this and had this problem already
Questions: Does anyone have a good idea/solution how to solve this situation correctly so that the range i received will be valid?
I think the easiest solution is to save copies of the iterators in range before you start the loop:
range = this->events.get().equal_range(boost::make_tuple(event,condition));
std::vector buff; while(range.first!=range.second)buff.push_back(range.first++);
for(std::size_t n=0,s=buff.size();n // CALL an event handler! this->callEventHandler(buff[n]); }
HTH,
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
hmm, great and easy solution, thx! but just to get better knowledge of (boost) iterators 1. what distinguishes 2 iterators of the same type? to ask it differently: given are 2 multi_index objects storing the same information 2. find() using the same search values will give me results on both objects - can i store the iterators in a vector OR a std::set without a problem? or will there be conflicts between the iterators, cause they are pointing to the same datatype? 3. is obj1.end()==obj2.end() true? thx @ ll _________________________________________________________________ Discover the new Windows Vista http://search.msn.com/results.aspx?q=windows+vista&mkt=en-US&form=QBRE

Prometheus Prometheus escribió:
hmm, great and easy solution, thx! but just to get better knowledge of (boost) iterators 1. what distinguishes 2 iterators of the same type? to ask it differently: given are 2 multi_index objects storing the same information 2. find() using the same search values will give me results on both objects - can i store the iterators in a vector OR a std::set without a problem? or will there be conflicts between the iterators, cause they are pointing to the same datatype?
You can jointly store iterators to different containers, no problem with that. You only have to be careful not to mix them: for instance, if it1 was obtained from obj1, you can't use it1 with obj2.
3. is obj1.end()==obj2.end() true?
No. This comparison is only legal if obj1 is the same as obj2. Otherwise, you are not even guaranteed that the comparison is defined :( as far as my understanding of the standard goes. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
joaquin@tid.es
-
Prometheus Prometheus