summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/_include/laws/logical.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/_include/laws/logical.hpp')
-rw-r--r--src/boost/libs/hana/test/_include/laws/logical.hpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/_include/laws/logical.hpp b/src/boost/libs/hana/test/_include/laws/logical.hpp
new file mode 100644
index 000000000..df9932766
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/logical.hpp
@@ -0,0 +1,137 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_TEST_LAWS_LOGICAL_HPP
+#define BOOST_HANA_TEST_LAWS_LOGICAL_HPP
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/concept/comparable.hpp>
+#include <boost/hana/core/when.hpp>
+#include <boost/hana/functional/capture.hpp>
+#include <boost/hana/lazy.hpp>
+#include <boost/hana/concept/logical.hpp>
+
+#include <laws/base.hpp>
+
+
+namespace boost { namespace hana { namespace test {
+ template <typename L, typename = when<true>>
+ struct TestLogical : TestLogical<L, laws> {
+ using TestLogical<L, laws>::TestLogical;
+ };
+
+ template <typename L>
+ struct TestLogical<L, laws> {
+ template <typename Xs, typename Pred, typename F>
+ static void for_each_such_that(Xs xs, Pred pred, F f) {
+ hana::for_each(xs, [&pred, &f](auto x) {
+ hana::eval_if(pred(x),
+ hana::make_lazy(f)(x),
+ [](auto) { }
+ );
+ });
+ }
+
+ template <typename Xs>
+ TestLogical(Xs xs) {
+ hana::for_each(xs, [](auto x) {
+ static_assert(Logical<decltype(x)>{}, "");
+ });
+
+ foreach3(xs, hana::capture(xs)([](auto xs, auto a, auto b, auto c) {
+ auto true_valued = [](auto x) {
+ return hana::if_(x, true_c, false_c);
+ };
+ auto false_valued = [](auto x) {
+ return hana::if_(x, false_c, true_c);
+ };
+
+ // associativity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(a, hana::or_(b, c)),
+ hana::or_(hana::or_(a, b), c)
+ ));
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(a, hana::and_(b, c)),
+ hana::and_(hana::and_(a, b), c)
+ ));
+
+ // equivalence through commutativity
+ BOOST_HANA_CHECK(
+ hana::or_(a, b) ^iff^ hana::or_(b, a)
+ );
+ BOOST_HANA_CHECK(
+ hana::and_(a, b) ^iff^ hana::and_(b, a)
+ );
+
+ // absorption
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(a, hana::and_(a, b)), a
+ ));
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(a, hana::or_(a, b)), a
+ ));
+
+ // left identity
+ TestLogical::for_each_such_that(xs, true_valued,
+ hana::capture(a)([](auto a, auto t) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(t, a), a
+ ));
+ }));
+ TestLogical::for_each_such_that(xs, false_valued,
+ hana::capture(a)([](auto a, auto f) {
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(f, a), a
+ ));
+ }));
+
+ // distributivity
+ BOOST_HANA_CHECK(hana::equal(
+ hana::or_(a, hana::and_(b, c)),
+ hana::and_(hana::or_(a, b), hana::or_(a, c))
+ ));
+ BOOST_HANA_CHECK(hana::equal(
+ hana::and_(a, hana::or_(b, c)),
+ hana::or_(hana::and_(a, b), hana::and_(a, c))
+ ));
+
+ // complements
+ BOOST_HANA_CHECK(true_valued(hana::or_(a, hana::not_(a))));
+ BOOST_HANA_CHECK(false_valued(hana::and_(a, hana::not_(a))));
+
+ }));
+ }
+ };
+
+ template <typename C>
+ struct TestLogical<C, when<Constant<C>::value>>
+ : TestLogical<C, laws>
+ {
+ template <typename Xs>
+ TestLogical(Xs xs) : TestLogical<C, laws>{xs} {
+ foreach2(xs, [](auto x, auto y) {
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(hana::not_(x)),
+ hana::not_(hana::value(x))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(hana::and_(x, y)),
+ hana::and_(hana::value(x), hana::value(y))
+ ));
+
+ BOOST_HANA_CHECK(hana::equal(
+ hana::value(hana::or_(x, y)),
+ hana::or_(hana::value(x), hana::value(y))
+ ));
+
+ });
+ }
+ };
+}}} // end namespace boost::hana::test
+
+#endif // !BOOST_HANA_TEST_LAWS_LOGICAL_HPP