Boost logo

Boost Users :

Subject: [Boost-users] Boost.MPL: Is it possible to apply a variable substitution without evaluating the lambda-expression?
From: Luke Simon (lsimon_at_[hidden])
Date: 2009-01-27 15:47:45


I am using BOOST_MPL_ASSERT to assert a lambda-expression applied to a
sequence of types by folding the lambda-expression onto a sequence of
types (see code and continue discussion below).

template<class predicate, class argument> struct mpl_assert
{
    typedef typename apply<predicate, argument>::type type;
    BOOST_MPL_ASSERT((type));
};

template<class pred, class xs> struct assert_for_all : foldr<
    mpl_assert<typename lambda<pred>::type, _>,
    true_,
    xs
> {};

The foldr metafunction is a strict version of Haskell's foldr, i.e.,
MPL's reverse_fold with parameters passed in the order that Haskell's
foldr passes parameters. The distinction isn't important for this
discussion, so don't dwell on that detail.

My intent is that if the lambda-expression is false for one of the types
in the sequence, then the lambda-expression applied to the "bad"
argument is printed in a compile-time error.

However, what gets printed is the result of the lambda-expression
applied to the bad argument: integral_constant<bool, false>, which is
very uninformative. If the definition of mpl_assert is changed to the
following:

template<class predicate, class argument> struct mpl_assert
{
    typedef typename apply<predicate, argument>::type type;
    BOOST_MPL_ASSERT((apply<predicate, argument>));
};

...then what gets printed is the unevaluated application of a
lambda-expression to the bad argument. While this is more informative,
it is still too messy because the type is a lambda-expression containing
placeholders.

The most desirable type to have printed would be the lambda-expression
after placeholder substitution, but before further evaluation. For
example, imagine:

typedef assert_for_all<is_same<foo, _>, boost::mpl::vector<foo, bar>
>::type type;

...the first definition of mpl_assert prints the following uninformative
type in the displayed error:

boost::integral_constant<bool, false>

...the second definition of mpl_assert prints the more descriptive but
overly messy type:

boost::mpl::apply<boost::mpl::protect<boost::mpl::bind2<boost::mpl::quote2<boost::is_same, mpl_::void_>, foo, mpl_::arg<-0x000000001> >, 0>, bar, mpl_::na, mpl_::na, mpl_::na, mpl_::na>

...but what I want to have printed is the type:

boost::is_same<foo, bar>

Boost.MPL is already calculating such a type, because apply<is_same<foo,
_>, bar> returns is_same<foo, bar>::type, so the needed type is there...
but does Boost.MPL provide a means of accessing it as opposed to
accessing its ::type field?


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net