Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-03-23 07:56:03


"Jaap Suter" <J.Suter_at_[hidden]> writes:

>> It could be an instantiation depth issue. Maybe the OP's code needs
>> more of our loop unrolling technique to avoid deep instantiations. I
>> think that can be controlled by #defining BOOST_MPL_UNROLLING_LIMIT
>> to some number greater than 4 before mpl files are #included.
>
> Thanks, I already managed to fix it.
>
> It turned out to be a classic case of Effective MPL- item 5.13 with some
> added recursion issues.
>
> It was just weird, because before the 1.30.0 release everything was working
> fine, so it was some combination of my old code with new mpl code that
> triggered this error.
> Luckily, after a nice and long debug session, I managed to track the problem
> down to an inner-most loop, and then I simply had to rewrite it to make it
> work.
>
> Thanks for your help,

Jaap, I was just looking over the EMPL Wiki page (which continues to
be a great thing), and noticed that item 5.2 is not really a good
example of MPL style. In fact, you apply equal_to to an integral
constant and access its ::value_type member so I think it won't even
compile. Make that thing a true MPL metafunction (i.e. operate on
types only) and you get something much simpler:

     template < class N, class Result = int_<0> >
     struct num_bits_set
         : apply_if<
              equal_to<
                    N
                  , integral_c< typename N::value_type, 0 >
>
            , Result
            , num_bits_set<
                  integral_c< size_t, bitand_<N, arg<prev<N> > >
                , next<Result>
>
>
    {};

That "arg" template is something that Aleksey and I have discussed
which causes a nullary metafunction to be evaluated in a lambda
expression. It may have another name in the current MPL sources; I'm
not absolutely sure (Aleksey?)

I also think it would be a great idea to have "zero" and "one"
metafunctions (which also satisfy the integral constant wrapper
requirements) so that we could write the above as:

     template < class N, class Result = int_<0> >
     struct num_bits_set
         : apply_if<
              equal_to<N, zero<N> >
            , Result
            , num_bits_set<
                  integral_c< size_t, bitand_<N, arg<prev<N> > >
                , next<Result>
>
>
    {};

If we wanted to get funky we could make it so zero<int_<3> > and
zero<long> both work.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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