Amit Prakash Ambasta <amit.prakash.ambasta <at> gmail.com> writes:
Hey Joaquin First of all, thank you so much for your repeated help.
You're welcome. Please don't top post, as suggested by Boost mailing lists guidelines: http://www.boost.org/community/policy.html
In line with the example provided, I've written a generic find_and_modify function as:
template <typename T, typename F> Segment* find_and_modify(T& iterable, F filters, State s, double a_arr=-1, Comment rmk=Comment::INFO_SEGMENT_PREDICTED) { auto iter = iterable.find(filters);
if (iter == iterable.end()) return nullptr;
std::pair<typename T::iterator, typename T::iterator> iter_main = iterable.equal_range(filters);
while (iter_main.first != iter_main.second) { auto it = boost::multi_index::project<aux>( segment, iter_main.first); segment.get<aux>().modify( it, [&s, &a_arr, &rmk](Segment& seg) { seg.state = s; if (a_arr != -1) seg.a_arr = a_arr;
if (rmk != +Comment::INFO_SEGMENT_PREDICTED) { seg.comment = rmk; } } ); iter_main.first++; }
return (Segment *)(&(*iter)); }
where T is an index on container instance segment as segment.get<sometag>();
This seems to work well for the most part but it still segfaults. Any ideas what I'm doing wrong. As specified in the SO answer, I've created an aux index and projected the current iterator to it so as to not modify the current iterator, and yet [...]
This is not helping at all because modify (no matter through which iterator is done) still can change the order of T so that your [iter_main.first,iter_main.second) loop fails. Put another way, the code auto it = boost::multi_index::project<aux>(segment, iter_main.first); segment.get<aux>().modify(it, ...); does exactly the same as T.modify(iter_main.first, ...); The answer in SO works because the loop is over the entire sequence [aux.begin(),aux.end()) (with aux=information_map_.get<idx_auxiliary>()), which is stable under modifications of the elements (it's a random-access index). This does not translate well to your scenario, where you need to loop over a subrange [a,b) of the sequence: for it to work [a,b) would have to project to a range [a',b') in the aux index, which of course is not the case (traversal orders are different).
I'd also like to point out that your approach via modify_unstable_range as per the boost mailing list works correctly though (however you've commented that it would be a slower approach)
Measure and if performance's OK stick to the modify_unstable_range approach. The aux index technique can be made to work with a little more effort (basically, by rearranging the index with rearrange()) but you might not need to anyway if modify_unstable_range is good enough (and there's no guarantee it's going to be faster to begin with). Joaquín M López Muñoz Telefónica