logical.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_HANA_TEST_LAWS_LOGICAL_HPP
  5. #define BOOST_HANA_TEST_LAWS_LOGICAL_HPP
  6. #include <boost/hana/assert.hpp>
  7. #include <boost/hana/bool.hpp>
  8. #include <boost/hana/concept/comparable.hpp>
  9. #include <boost/hana/core/when.hpp>
  10. #include <boost/hana/functional/capture.hpp>
  11. #include <boost/hana/lazy.hpp>
  12. #include <boost/hana/concept/logical.hpp>
  13. #include <laws/base.hpp>
  14. namespace boost { namespace hana { namespace test {
  15. template <typename L, typename = when<true>>
  16. struct TestLogical : TestLogical<L, laws> {
  17. using TestLogical<L, laws>::TestLogical;
  18. };
  19. template <typename L>
  20. struct TestLogical<L, laws> {
  21. template <typename Xs, typename Pred, typename F>
  22. static void for_each_such_that(Xs xs, Pred pred, F f) {
  23. hana::for_each(xs, [&pred, &f](auto x) {
  24. hana::eval_if(pred(x),
  25. hana::make_lazy(f)(x),
  26. [](auto) { }
  27. );
  28. });
  29. }
  30. template <typename Xs>
  31. TestLogical(Xs xs) {
  32. hana::for_each(xs, [](auto x) {
  33. static_assert(Logical<decltype(x)>{}, "");
  34. });
  35. foreach3(xs, hana::capture(xs)([](auto xs, auto a, auto b, auto c) {
  36. auto true_valued = [](auto x) {
  37. return hana::if_(x, true_c, false_c);
  38. };
  39. auto false_valued = [](auto x) {
  40. return hana::if_(x, false_c, true_c);
  41. };
  42. // associativity
  43. BOOST_HANA_CHECK(hana::equal(
  44. hana::or_(a, hana::or_(b, c)),
  45. hana::or_(hana::or_(a, b), c)
  46. ));
  47. BOOST_HANA_CHECK(hana::equal(
  48. hana::and_(a, hana::and_(b, c)),
  49. hana::and_(hana::and_(a, b), c)
  50. ));
  51. // equivalence through commutativity
  52. BOOST_HANA_CHECK(
  53. hana::or_(a, b) ^iff^ hana::or_(b, a)
  54. );
  55. BOOST_HANA_CHECK(
  56. hana::and_(a, b) ^iff^ hana::and_(b, a)
  57. );
  58. // absorption
  59. BOOST_HANA_CHECK(hana::equal(
  60. hana::or_(a, hana::and_(a, b)), a
  61. ));
  62. BOOST_HANA_CHECK(hana::equal(
  63. hana::and_(a, hana::or_(a, b)), a
  64. ));
  65. // left identity
  66. TestLogical::for_each_such_that(xs, true_valued,
  67. hana::capture(a)([](auto a, auto t) {
  68. BOOST_HANA_CHECK(hana::equal(
  69. hana::and_(t, a), a
  70. ));
  71. }));
  72. TestLogical::for_each_such_that(xs, false_valued,
  73. hana::capture(a)([](auto a, auto f) {
  74. BOOST_HANA_CHECK(hana::equal(
  75. hana::or_(f, a), a
  76. ));
  77. }));
  78. // distributivity
  79. BOOST_HANA_CHECK(hana::equal(
  80. hana::or_(a, hana::and_(b, c)),
  81. hana::and_(hana::or_(a, b), hana::or_(a, c))
  82. ));
  83. BOOST_HANA_CHECK(hana::equal(
  84. hana::and_(a, hana::or_(b, c)),
  85. hana::or_(hana::and_(a, b), hana::and_(a, c))
  86. ));
  87. // complements
  88. BOOST_HANA_CHECK(true_valued(hana::or_(a, hana::not_(a))));
  89. BOOST_HANA_CHECK(false_valued(hana::and_(a, hana::not_(a))));
  90. }));
  91. }
  92. };
  93. template <typename C>
  94. struct TestLogical<C, when<Constant<C>::value>>
  95. : TestLogical<C, laws>
  96. {
  97. template <typename Xs>
  98. TestLogical(Xs xs) : TestLogical<C, laws>{xs} {
  99. foreach2(xs, [](auto x, auto y) {
  100. BOOST_HANA_CHECK(hana::equal(
  101. hana::value(hana::not_(x)),
  102. hana::not_(hana::value(x))
  103. ));
  104. BOOST_HANA_CHECK(hana::equal(
  105. hana::value(hana::and_(x, y)),
  106. hana::and_(hana::value(x), hana::value(y))
  107. ));
  108. BOOST_HANA_CHECK(hana::equal(
  109. hana::value(hana::or_(x, y)),
  110. hana::or_(hana::value(x), hana::value(y))
  111. ));
  112. });
  113. }
  114. };
  115. }}} // end namespace boost::hana::test
  116. #endif // !BOOST_HANA_TEST_LAWS_LOGICAL_HPP