Boost logo

Boost Users :

From: Bruno Martínez (br1_at_[hidden])
Date: 2006-04-26 01:02:58


On Tue, 25 Apr 2006 23:11:26 -0300, Greg Link <link_at_[hidden]> 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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net