
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

klaus triendl wrote:
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.
Well, fold is far more generic than for. I can't see, in a meta-programming context where side-effects don't occur, when having for_ is needed when we have fold_. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

"joel" <joel.falcou@lri.fr> schrieb im Newsbeitrag news:4A9CDA69.5080202@lri.fr...
klaus triendl wrote:
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.
Well, fold is far more generic than for. I can't see, in a meta-programming context where side-effects don't occur, when having for_ is needed when we have fold_.
fold expects a sequence container; I don't see how I can use fold if I don't have one - see the cross_total metafunction in my initial posting. Like one can't use std::for_each or std::accumulate in every situation - or the usage would get complicated at least -, for_ has its purpose, I think. Klaus

On 09/01/09 03:12, klaus triendl wrote:
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: [snip] This sounds like while_recur found here:
https://svn.boost.org/trac/boost/attachment/ticket/3044/while_recur.cpp This was part of a proposed patch to mpl's iter_fold_if to solve a problem another booster had: http://article.gmane.org/gmane.comp.lib.boost.devel/190874/match=or_seq However, for some reason (people too busy or maybe there's some bug someone's seen in while_recur), the topic's cooled off since there's no posts since 6/10/2009 :(

"Larry Evans" <cppljevans@suddenlink.net> schrieb im Newsbeitrag news:h7iq50$pjj$1@ger.gmane.org...
On 09/01/09 03:12, klaus triendl wrote:
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: [snip] This sounds like while_recur found here:
https://svn.boost.org/trac/boost/attachment/ticket/3044/while_recur.cpp
This was part of a proposed patch to mpl's iter_fold_if to solve a problem another booster had:
http://article.gmane.org/gmane.comp.lib.boost.devel/190874/match=or_seq
However, for some reason (people too busy or maybe there's some bug someone's seen in while_recur), the topic's cooled off since there's no posts since 6/10/2009 :(
while_recur looks very similar to what I've thought of, but it can't do what I want (e.g. can't calculate the cross total from a given number) The for-loop I imagine has two important characteristics: 1) resembles a runtime for-loop 2) loop expressions are separate from the state to calculate pseudo runtime code to illustrate what I mean: type state; for(type loopvalue = start; looptest(loopvalue); loopvalue = binarynext(state, loopvalue)) { state = binaryop(state, loopvalue); } Klaus

Il giorno 02/set/2009, alle ore 23.17, "klaus triendl" <klaus@triendl.eu> ha scritto:
The for-loop I imagine has two important characteristics: 1) resembles a runtime for-loop 2) loop expressions are separate from the state to calculate
pseudo runtime code to illustrate what I mean: type state; for(type loopvalue = start; looptest(loopvalue); loopvalue = binarynext(state, loopvalue)) { state = binaryop(state, loopvalue); }
This construct is well known among functional programmers and is called unfold as is the dual of fold -- Gpd

On 09/02/09 16:17, klaus triendl wrote:
"Larry Evans" <cppljevans@suddenlink.net> schrieb im Newsbeitrag news:h7iq50$pjj$1@ger.gmane.org...
On 09/01/09 03:12, klaus triendl wrote:
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:
[snip] This sounds like while_recur found here:
https://svn.boost.org/trac/boost/attachment/ticket/3044/while_recur.cpp
This was part of a proposed patch to mpl's iter_fold_if to solve a problem another booster had:
http://article.gmane.org/gmane.comp.lib.boost.devel/190874/match=or_seq
However, for some reason (people too busy or maybe there's some bug someone's seen in while_recur), the topic's cooled off since there's no posts since 6/10/2009 :(
while_recur looks very similar to what I've thought of, but it can't do what I want (e.g. can't calculate the cross total from a given number)
The for-loop I imagine has two important characteristics: 1) resembles a runtime for-loop 2) loop expressions are separate from the state to calculate
pseudo runtime code to illustrate what I mean: type state; for(type loopvalue = start; looptest(loopvalue); loopvalue = binarynext(state, loopvalue)) { state = binaryop(state, loopvalue); }
I'm not convinced. You seem to be saying that a for loop can do something that a while loop can't. I thought a for loop was a "specialization" of a while loop; hence, anything a for loop does can be done by a while loop with some initialization. For example, the for loop you mention: type state; for ( type loopvalue = start ; looptest(loopvalue) ; loopvalue = binarynext(state, loopvalue) ) { state = binaryop(state, loopvalue); } is equivalent to: type loopvalue = start; type loopstate = init_state; while(looptest(loopvalue)) { loopstate = binarynext(loopstate, loopvalue) ; loopvalue = binarynext_value(loopstate, loopvalue) } Where loopstate is the for loop state and the init_state and binarynext_value are missing from the for loop. IOW, for while_recur, the state would be while_state = pair(loopvalue,loopstate) with the hopefully obvious definition of while_next and while_test written in terms of the binarynext and binarynext_value. StateValue(start) = pair(_,value); looptestStateValue(pair(state,value) = looptest(value) binaryopStateValue(pair(state,value) = pair(binaryop(state,value) Could you be more explicit about why while_recur can't do something which your for_ can do? -regards, Larry
participants (4)
-
Gpderetta
-
joel
-
klaus triendl
-
Larry Evans