Boost logo

Boost :

Subject: Re: [boost] Phoenix Reloaded
From: Eric Niebler (eric_at_[hidden])
Date: 2009-05-29 22:15:18


> Eric Niebler wrote:
>> The top two templates instantiated in this program are mpl::if_ and
>> mpl::if_c, respectively. The sad thing is that most of the
>> instantiations of mpl::if_c are totally unnecessary. mpl::if_ happens
>> to
>> be implemented in terms of mpl::if_c so that any instantiation of
>> mpl::if_ causes an additional instantiation of mpl::if_c.

 From more profiling, I see that another main offender of needless
template instantiations is mpl::sequence_tag, implemented as follows:

template<
       typename BOOST_MPL_AUX_NA_PARAM(Sequence)
>
struct sequence_tag
     : aux::sequence_tag_impl<
           ::boost::mpl::aux::has_tag<Sequence>::value
         , ::boost::mpl::aux::has_begin<Sequence>::value
>::template result2_<Sequence>
{
};

This metafunction is invoked from *everywhere*, and each instantiation
of sequence_tag causes additional instantiations to: has_tag, has_begin,
sequence_tag_impl, and sequence_tag_impl::result2_. Yech.

Here's a different implementation that cuts that reduces it from 5
instantiations to 2. Figuring out which compilers accept this is left as
an exercise to the reader. ;-)

     namespace aux {

     typedef char sequence_tag_impl_has_tag;
     typedef char (&sequence_tag_impl_has_begin)[2];
     typedef char (&sequence_tag_impl_has_neither)[3];

     template< typename Sequence > sequence_tag_impl_has_tag
test_sequence_tag_impl(Sequence *, typename Sequence::tag *, typename
Sequence::begin *);
     template< typename Sequence > sequence_tag_impl_has_tag
test_sequence_tag_impl(Sequence *, typename Sequence::tag *, ...);
     template< typename Sequence > sequence_tag_impl_has_begin
test_sequence_tag_impl(Sequence *, typename Sequence::begin *, ...);
     template< typename Sequence > sequence_tag_impl_has_neither
test_sequence_tag_impl(Sequence *, ...);

     template< typename Sequence, std::size_t SequenceType >
     struct sequence_tag_impl
     {
         typedef non_sequence_tag type;
     };

     template< typename Sequence >
     struct sequence_tag_impl< Sequence, sizeof(sequence_tag_impl_has_tag) >
     {
         typedef typename Sequence::tag type;
     };

     template< typename Sequence >
     struct sequence_tag_impl< Sequence,
sizeof(sequence_tag_impl_has_begin) >
     {
         typedef nested_begin_end_tag type;
     };

     } // namespace aux

     template<
           typename BOOST_MPL_AUX_NA_PARAM(Sequence)
>
     struct sequence_tag
         : aux::sequence_tag_impl<
               Sequence
             ,
sizeof(::boost::mpl::aux::test_sequence_tag_impl<Sequence>(0,0,0))
>
     {
     };

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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