Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-03-23 13:10:25

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

>> 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.
> The original intention was to focus on the default-template-parameter
> technique, and keep the rest simple. The 'operate-on-types-only' is
> introduced in a later item, so I wanted to keep this item simple.
> Looking back, I agree with you, so I've changed the code.

Good. I think a few more of those examples bear changing in the same
way. TMP of any complexity really is simpler if you just give up on
direct handling of integral constants.

>> In fact, you apply equal_to to an integral
>> constant and access its ::value_type member so I think it won't even
>> compile.
> That was of course completely wrong.
>> 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've done it somewhat differently in the new code.

Eh, whoops; your template invokes num_bits_set_impl, which isn't
defined. Also, next is spelled "netxt". I also think you may have a
problem with eager evaluation or one too many ::type s. I think you
should test these.

Why aren't you at least using forwarding? You already introduced it
in an earlier item; there's no reason to make it more complicated
than it needs to be. Off the top of my head:

 template < class N, class Result = integral_c< size_t, 0 > >
 struct num_bits_set
    : apply_if<
         equal_to< N, integral_c< typename N::value_type, 0 > >
       , Result
       , num_bits_set<
             mpl::bitand_<N, typename N::prior>, typename Result::next

I want to suggest also that personal preferences aside, your choice
of enline layout in your formatting may cause enough of the structure
of the calculation to be obscured that you missed the errors.

>> I also think it would be a great idea to have "zero" and "one"
>> metafunctions (which also satisfy the integral constant wrapper
>> requirements) If we wanted to get funky we could make it so
>> zero<int_<3> > and zero<long> both work.
> Those would be greatly appreciated, and very useful.

Care to submit some files? This seems like a super-easy job.

> On a side note, I've ran into a few situations where I ended up using code
> like this:
> typedef list_c< some_type, 0, 1, 2, 3, 4 > some_list;
> typedef integral_c< front< some_list >::type::value_type, 5 > some_element;
> See what I'm trying to do? I need to get the type of the integral constants
> inside a list, so I just get it through the first element in the list.
> This doesn't work with empty list though, and it feels too complicated to do
> this. Is there a simpler method?

Not yet, AFAICT.

> Something like:
> typedef integral_c< some_list::element_type::value_type, 5 > some_element;
> Notice the 'element_type'. All sequences would then have such a member-type
> defined.

That won't work for generalized type sequences, of course:

     list<int, double, std::string>

I think the integral sequence wrappers might be able to have a
::value_type directly, but that could also complicate algorithms which
have to produce new sequences, since to be useful they'd need to
transfer the ::value_type to the new sequence iff it existed in the
original one. We could give sequences a ::value_type of mpl::void_ by
default I guess, but all of these ideas feel conceptually pretty hairy
to me. Remember that the integral sequences are conceptually just
convenient front-ends for regular type sequences.

> Perhaps there is already something like this in the MPL (STL has it too,
> probably under a different name), but I couldn't find it.

STL calls it value_type.

I understand the need you have, but I am really unsure of the best
way to address it.

Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at