|
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