[Home]CPPTM Answers - Exercise 4-1

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

 // (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;
}

BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited May 2, 2008 11:39 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers