Boost logo

Boost :

Subject: [boost] compile-time for-loop
From: klaus triendl (klaus_at_[hidden])
Date: 2009-09-01 04:12:25


I wonder whether a compile-time for-loop is useful enough so that it would
get included in the mpl library;
it's very similar to what fold does but it can be used for computations with
types other than sequence
containers.

The loop construct takes a start value, a loop condition and a
function calculating the next start value for the next loop recursion and
additionally a state together with a binary operation serving as loop
body:

namespace boost { namespace mpl {

template<
      typename Start, typename UnaryLoopTest, typename BinaryNext
    , typename State, typename BinaryOp
>
struct for_:
    eval_if<
        // loop as long as the loop condition yields true
        typename apply<
            UnaryLoopTest,
            typename Start::type
>::type,
        // next loop iteration: recursive call
        for_<
            // calculate next loop value
            typename apply<
                BinaryNext,
                State,
                typename Start::type
>::type,
            // pass on UnaryLoopTest and pass on BinaryNext
            UnaryLoopTest, BinaryNext,
            // calculate next state
            typename apply<
                BinaryOp,
                State,
                typename Start::type
>::type,
            // pass on BinaryOp
            BinaryOp
>,
        // loop termination if loop condition yields false
        State
>
{};

} }

// That's an example how to use the for-loop:

using namespace boost;

template<typename T, T N>
struct cross_total:
        mpl::for_<
            // start
            mpl::integral_c<T, N>,
            // loop condition
            mpl::not_equal_to<mpl::_1, mpl::integral_c<T, 0> >,
            // calculate next value
            mpl::divides<mpl::_2, mpl::int_<10> >,
            // state = current cross sum of already iterated digits
            mpl::int_<0>,
            // binary function is loop body: crosstotal += digit
            mpl::plus<
                mpl::_1,
                mpl::modulus<mpl::_2, mpl::int_<10> >
>
>::type
{};
</code>

More useful may be to calculate a number's digits for any base, which
can be used to calculate the required maximum storage size for a type (I
know that there's std::numeric_limits<> but this one would be more general).

Klaus Triendl


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk