$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Jaap Suter (boost_at_[hidden])
Date: 2004-11-15 16:40:47
Hello,
can any compiler expert give me feedback on whether there should be a
noticable difference in compilation speed between the following two
meta-functions:
template<class N, class M, class Q, class P>
struct foo : mpl::plus
<
N,
typename mpl::minus
<
M,
typename mpl::divides
<
Q,
P
>::type
>::type
>::type
{};
and
template<int N, int M, int P, int Q>
struct foo
{
enum
{
value = N + (M - (Q/P))
};
typedef boost::mpl::int<value> type;
}
The second version saves me a lot of template instantiations and many
header inclusions, at the cost of losing some genericity.
On the other hand, if the calculation becomes complicated, I find myself
using many enums to hold intermediate values, resulting in code like the
following:
template<class T>
struct next_number_with_same_num_bits
{
enum
{
lowest_bit_set = T::value & (-T::value),
lowest_bit_set_index = count_leading_zeroes<T>::type::value,
next_t = T::value + lowest_bit_set,
next_lowest_set_bit = next_t & (-next_t),
mask = next_lowest_set_bit - lowest_bit_set,
result_t = next_t | (mask >> (lowest_bit_set_index + 1))
};
typedef boost::mpl::int_<result_t> type;
};
which leads MSVC to run out of so-called compiler-keys much
quicker than if I reduce the above to the completely unreadable:
template<class T>
struct next_number_with_same_num_bits
{
enum
{
result_t = (T::value + (T::value & (-T::value))) | ((((T::value +
(T::value & (-T::value))) & (-T::value - (T::value & (-T::value)))) -
(T::value & (-T::value))) >> (count_leading_zeroes<T>::type::value + 1))
};
typedef boost::mpl::int_<result_t> type;
};
Does anybody have any thoughts or comments on this technique, and is anybody
else using tricks around MPL to make sure your compiler still handles
things?
Thanks,
Jaap Suter