Boost logo

Boost Users :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-03-16 21:09:52


Hi Scott,

Scott Meyers wrote:
> I'm trying to use the MPL for the first time, and I have two questions.
> First, I want to use BOOST_MPL_ASSERT to say that at least one of two
> conditions is true. For the time being, one of the conditions is always
> false, so this is what I've tried:
>
> BOOST_MPL_ASSERT((
> false
> ||
> boost::is_same<CallerConstraints,
> CodeConstraints::Ignore_Constraints>
> ));
>
> It won't compile, so I tried this:
>
> BOOST_MPL_ASSERT((
> mpl::or_(false,
> boost::is_same<CallerConstraints,
> CodeConstraints::Ignore_Constraints>)
> ));
>
> It won't compile either. I'm guessing that I have to use mpl::false_ or
> something in place of false, but that doesn't work either. Can somebody
> please tell me the proper way to say what I want to say?

Since we're in the "type system world", there are no (unwrapped)
constants - there are types and only types. So, there are no function
calls, round parentheses and no operators - we have to use class
templates, /metafunctions/, for the operations, because their
specializations are types and they can hold a nested 'type' member for
the result -- even templates and constants (but for returning lesser
beings like that we use a 'type' member pointing back to the nesting
class to have a proper metafunction).

     #include <boost/mpl/assert.hpp>
     #include <boost/mpl/bool.hpp>
     #include <boost/mpl/or.hpp>

     #include <boost/type_traits/is_same.hpp>

     using namespace boost;

     struct my_constant // to demystify mpl::false_
     {
         static bool const value = false;
         typedef my_constant type;
         typedef bool value_type;
     };

     typedef void type1;
     typedef void type2;

     BOOST_MPL_ASSERT(( mpl::or_< my_constant, mpl::false_,
is_same<type1, type2> > ));

Alternatively there's a non-MPL component, 'BOOST_STATIC_ASSERT', that
takes a real constant.

Using BOOST_STATIC_ASSERT we'd say:

     #include <boost/static_assert.hpp>

     #include <boost/type_traits/is_same.hpp>

     using namespace boost;

     typedef void type1;
     typedef void type2;

     BOOST_STATIC_ASSERT(( false || is_same<type1,type2>::value ));
     // Note: accessing nested value constant in is_same specialization
     // Also note: We'd have to say ::boost::is_same<type1,type2>::value
     // to please some broken compilers

> My second question is about the existence of an MPL algorithm akin to
> the STL algorithm includes. Given two MPL vectors V1 and V2, I want to
> know if all the types in V1 are also in V2. I know about mpl::contains,
> but I can't find mpl::includes. Is there one, or do I need to write it
> myself?

I'd probably do it like this:

     #include <boost/mpl/vector.hpp>
     #include <boost/mpl/assert.hpp>

     #include <boost/mpl/count_if.hpp>
     #include <boost/mpl/not.hpp>
     #include <boost/mpl/contains.hpp>
     #include <boost/mpl/placeholders.hpp>

     using namespace boost;
     using namespace mpl::placeholders;

     typedef mpl::vector<int,char,float> seq1;
     typedef mpl::vector<double,float,char,int> seq2;

     // make sure all elements in seq1 are also in seq2
     BOOST_MPL_ASSERT_NOT((
         mpl::count_if< seq1, mpl::not_< mpl::contains<seq2, _> > >
     ));

...because I'm lazy. It's not optimal because we keep iterating 'seq1'
even if we already found a mismatch. It can be fixed by using 'find_if'
instead and comparing the result (its nested 'type' member) against the
end iterator of 'seq1'.

> I have the MPL book, so references to that are fine, in addition to
> anything online.

Still missing in my collection, unfortunately. Still waiting for the
discount price together with "Effective MPL" ;-)...

Regards,
Tobias


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