$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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