// (by Ariel Badichi) #include <boost/static_assert.hpp> #include <boost/mpl/bool.hpp>
namespace mpl = boost::mpl;
class error {}; // no ::type
template<bool B, typename T2> struct logical_or_;
template<typename T2> struct logical_or_<false, T2> { typedef typename T2::type type; };
template<typename T2> struct logical_or_<true, T2> { typedef mpl::true_ type; };
template<typename T1, typename T2> struct logical_or { static const bool v1 = T1::type::value; typedef typename logical_or_<v1, T2>::type type; };
template<bool B, typename T2> struct logical_and_;
template<typename T2> struct logical_and_<false, T2> { typedef mpl::false_ type; };
template<typename T2> struct logical_and_<true, T2> { typedef typename T2::type type; };
template<typename T1, typename T2> struct logical_and { static const bool v1 = T1::type::value; typedef typename logical_and_<v1, T2>::type type; };
int main() { BOOST_STATIC_ASSERT((logical_or<mpl::true_, error>::type::value)); BOOST_STATIC_ASSERT((!logical_or<mpl::false_, mpl::false_>::type::value)); BOOST_STATIC_ASSERT((!logical_and<mpl::false_, error>::type::value)); BOOST_STATIC_ASSERT((logical_and<mpl::true_, mpl::true_>::type::value));
return 0; }
// (by Noah Roberts - Engineered Software INC.) #include <boost/static_assert.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/not.hpp> /* ** The other answer is quite different. It does not make use of existing MPL ** functionality nor is logical_and_ implemented in terms of logical_or_ as I have done. ** ** That answer also implements logical_and_ and logical_or_ so that they accept a bool as the first ** argument. The MPL versions do not do this and I see nothing in the exercize that expects it. ** I don't think it reasonable to do, especially since the other answer does not accept ** bool as the second argument. This is just an added inconsistency with not much benefit (wouldn't ** have to put it in a mpl::bool_<value> type). */ template < typename T1, typename T2 > struct logical_or_ : boost::mpl::if_< T1, T1, T2 >::type { }; template < typename T1, typename T2 > struct logical_and_ : boost::mpl::not_< logical_or_< boost::mpl::not_<T1>, boost::mpl::not_<T2> > >::type { }; struct error {}; int main(void) { using boost::mpl::true_; using boost::mpl::false_; BOOST_STATIC_ASSERT((logical_or_ < true_, true_ >::value)); BOOST_STATIC_ASSERT((logical_or_ < true_, false_ >::value)); BOOST_STATIC_ASSERT((logical_or_ < false_, true_ >::value)); BOOST_STATIC_ASSERT((!logical_or_ < false_, false_ >::value)); BOOST_STATIC_ASSERT((logical_or_<true_, error>::value)); BOOST_STATIC_ASSERT((logical_and_<true_, true_ >::value)); BOOST_STATIC_ASSERT((!logical_and_<true_, false_>::value)); BOOST_STATIC_ASSERT((!logical_and_<false_, true_>::value)); BOOST_STATIC_ASSERT((!logical_and_<false_, false_>::value)); BOOST_STATIC_ASSERT((!logical_and_<false_, error>::value)); return 0; }