Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-06-26 10:08:09


On Wednesday 26 June 2002 10:09 am, Douglas Gregor wrote:
> We'll see. Using MPL's placeholders there are a few areas where the variant
> code size could be reduced (for instance, there should be no need for
> details::add_const or details::max_size)

Some examples:

The computation of 'max_size' in the variant class used to use 26 lines of
code in two auxiliary classes (details::max_size and
details::sizeof_comparison). Instead, just use:

        BOOST_STATIC_CONSTANT(size_t,
          max_size = sizeof(typename mpl::max_element<
                              types,
                              mpl::less<mpl::size_of<mpl::_1>,
                                        mpl::size_of<mpl::_2> >
>::type));

Similarly, the computation of the alignment type 'align' was 33 lines, but can
be written as:

        BOOST_STATIC_CONSTANT(size_t,
          max_align = (alignment_of<
                         typename mpl::max_element<
                           types,
                           mpl::less<details::align_of<mpl::_1>,
                                     details::align_of<mpl::_2> >
>::type>::value));

        typedef typename type_with_alignment<max_align>::type align;

The align_of template is a simple wrapper around the alignment_of template in
the type traits library; I expect the need for this wrapper would disappear
in future versions if MPL is accepted. align_of looks like this:

        template<typename T>
        struct align_of : public alignment_of<T>
        {
          typedef mpl::integral_c<std::size_t,value> type;
        };

Finally, the 'is_not_convertible_from' metafunction is also unnecessary. We
can use placeholders instead. So the metafunction object
is_not_convertible_from<T> is just:

  mpl::logical_not<is_convertible<T, mpl::_1> >

That saves another 11 lines.

Two comments:
  1) I don't think the MPL lambda facilities work under MSVC :(
  2) I had to make two bugfixes in MPL: neither apply_if nor max_element were
applying mpl::lambda to their predicates. They need to.

Just for a quick comparison, here's the max_align calculation with type lists:

template<typename List> struct get_max_align;

template<typename H, typename T>
struct get_max_align<cons<H, T> >
{
  enum { a1 = alignment_of<H>::value };
  enum { a2 = get_max_align<T>::align };
  enum { align = a1 > a2? a1 : a2 };
};

template<>
struct get_max_align<nil>
{
  enum { align = 1 };
};

13 lines for the typelist version vs. 7 lines for the MPL version. The
important question is: which is more readable?

        Doug


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