
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