|
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