
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