
Jeff Flinn wrote:
It would be nice to have a modify_range/modify_key_range that would apply a function object to each deref'd iterator in the range. Since the multi_index iterator derefences to a const value_type&, one can not use std::for_each in particular to apply modifications. Or am I missing something.
Hello Jeff, I think it is possible to have what you want without requiring that a new facility be provided by Boost.MultiIndex itself. For you can write: template<typename Index,typename Modifier> void modify_range( Index& i,typename Index::iterator first,typename Index::iterator last, Modifier mod) { while(first!=last)i.modify(first++,mod); } and use it as in the following example: struct adder { adder(int n):n(n){} void operator()(int& x)const{x+=n;} private: int n; }; typedef multi_index_container< int, indexed_by< ordered_non_unique<boost::multi_index::identity<int> > >
multi_index_type;
multi_index_type m; for(int i=0;i<10;++i)m.insert(i); modify_range(m,m.begin(),m.end(),adder(-2)); or with Boost.Lambda if you prefer: modify_range(m,m.begin(),m.end(),_1-=2); There is a problem, though: consider the following: // buggy call ro modify_range modify_range(m,m.begin(),m.end(),adder(2)); What's the problem with this? Well, after *increasing* the value of an element, this is repositioned further to the end of the container, and consequentely modify_range will visit it again and engage in a neverending loop (modulo overflows.) For this situations you can use a special (albeit slower) variation that records the range before starting modifying the elements: template<typename Index,typename Modifier> void modify_unstable_range( Index& i,typename Index::iterator first,typename Index::iterator last, Modifier mod) { typedef std::vector<typename Index::iterator> buffer_type; buffer_type v; while(first!=last)v.push_back(first++); for(typename buffer_type::iterator it=v.begin(),it_end=v.end(); it!=it_end;i.modify(*it++,mod)); } // calling modify_unstable_range is now OK modify_unstable_range(m,m.begin(),m.end(),adder(2)); I hope my explanations are clear enough. Does this satisfy your needs? You can find attached a complete example exercising these little utilities. modify_key_range would be a simple variation on this stuff. HTH, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo