
On Tue, 25 Apr 2006 23:11:26 -0300, Greg Link <link@cse.psu.edu> wrote:
I would agree with you there - a 'foreach' would do what I need as well, but as I'm not 100% familiar with the way libraries such as boost are implemented, I worry that making your own control structure is much more difficult than making an accessor/modifier pair. I can't even imagine the syntax needed to convert the following into a theoretical boost-defined 'foreach'
I didn't mean new sintax, but a std::for_each work-alike.
double previous = 0; double accumulator = 0; for(iterator_t myIterator = m_array.data(); myIterator != m_array.end (); myIterator++) { accumulator += (*myIterator); (*myIterator) *= previous accumulator = (previous > 7) ? (do_function(accumulator)) : (0); }
You can do that with Boost.Lambda: #include <boost/lambda/lambda.hpp> #include <boost/lambda/if.hpp> #include <boost/lambda/bind.hpp> #include <algorithm> int main() { double previous = 0; double accumulator = 0; double d[3] = {1, 2, 3}; using boost::lambda::_1; using boost::lambda::if_then_else_return; using boost::lambda::var; using boost::lambda::bind; std::for_each(&d[0], &d[3], ( accumulator += _1, _1 *= previous, var(accumulator) = if_then_else_return(var(previous) > 7, bind(&do_function, accumulator), 0))); } I spend some time today writing a std::for_each-like function for multiarrays. This works correctly for subviews, but isn't as convenient as an iterator. You can't iterate through two multiarrays at the same time, for example. I only tested with MSVC8, so there may be some typenames missing. Here it is: template<class MA, class F, int dim> struct for_each_impl { F f; for_each_impl(F f) : f(f) {} void operator()(MA& ma) { std::for_each(ma.begin(), ma.end(), for_each_impl<typename MA::reference, F, dim-1>(f)); } }; template<class Ref, class F> struct for_each_impl<Ref, F, 0> { F f; for_each_impl(F f) : f(f) {} void operator()(Ref r) { f(r); } }; template<class MA, class F> void for_each(MA& ma, F f) { for_each_impl<MA, F, MA::dimensionality> impl(f); impl(ma); } And a test: typedef boost::multi_array<double, 3> array_type; typedef array_type::index index; array_type myarray(boost::extents[3][4][2]); typedef array_type::index_range range; array_type::array_view<3>::type myview = myarray[ boost::indices[range(0,2)][range(1,3)][range(0,4,2)] ]; for_each(myview, _1 = 56); Hope that helps. Bruno