// 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_EUCLIDEAN_RING_HPP #define BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace hana { namespace test { template > struct TestEuclideanRing : TestEuclideanRing { using TestEuclideanRing::TestEuclideanRing; }; template struct TestEuclideanRing { template TestEuclideanRing(Xs xs) { hana::for_each(xs, [](auto x) { static_assert(EuclideanRing{}, ""); }); #ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 zero(); // force adding zero's member function to pending temploid list #endif foreach2(xs, [](auto a, auto b) { // commutativity BOOST_HANA_CHECK(hana::equal( hana::mult(a, b), hana::mult(b, a) )); only_when_(hana::not_equal(b, zero()), hana::make_lazy([](auto a, auto b) { BOOST_HANA_CHECK(hana::equal( hana::plus( hana::mult(hana::div(a, b), b), hana::mod(a, b) ), a )); BOOST_HANA_CHECK(hana::equal( hana::mod(zero(), b), zero() )); })(a, b)); }); } }; template struct TestEuclideanRing::value>> : TestEuclideanRing { template TestEuclideanRing(Xs xs) : TestEuclideanRing{xs} { foreach2(xs, [](auto x, auto y) { only_when_(hana::not_equal(zero(), y), hana::make_lazy([](auto x, auto y) { BOOST_HANA_CHECK(hana::equal( hana::div(hana::value(x), hana::value(y)), hana::value(hana::div(x, y)) )); BOOST_HANA_CHECK(hana::equal( hana::mod(hana::value(x), hana::value(y)), hana::value(hana::mod(x, y)) )); })(x, y)); }); } }; }}} // end namespace boost::hana::test #endif // !BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP