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 5 #ifndef BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP 6 #define BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP 7 8 #include <boost/hana/assert.hpp> 9 #include <boost/hana/bool.hpp> 10 #include <boost/hana/concept/comparable.hpp> 11 #include <boost/hana/concept/constant.hpp> 12 #include <boost/hana/concept/euclidean_ring.hpp> 13 #include <boost/hana/core/when.hpp> 14 #include <boost/hana/div.hpp> 15 #include <boost/hana/equal.hpp> 16 #include <boost/hana/for_each.hpp> 17 #include <boost/hana/lazy.hpp> 18 #include <boost/hana/mod.hpp> 19 #include <boost/hana/mult.hpp> 20 #include <boost/hana/not_equal.hpp> 21 #include <boost/hana/plus.hpp> 22 #include <boost/hana/value.hpp> 23 #include <boost/hana/zero.hpp> 24 25 #include <laws/base.hpp> 26 27 28 namespace boost { namespace hana { namespace test { 29 template <typename D, typename = when<true>> 30 struct TestEuclideanRing : TestEuclideanRing<D, laws> { 31 using TestEuclideanRing<D, laws>::TestEuclideanRing; 32 }; 33 34 template <typename D> 35 struct TestEuclideanRing<D, laws> { 36 template <typename Xs> TestEuclideanRingboost::hana::test::TestEuclideanRing37 TestEuclideanRing(Xs xs) { 38 hana::for_each(xs, [](auto x) { 39 static_assert(EuclideanRing<decltype(x)>{}, ""); 40 }); 41 42 #ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 43 zero<D>(); // force adding zero<D>'s member function to pending temploid list 44 #endif 45 46 foreach2(xs, [](auto a, auto b) { 47 48 // commutativity 49 BOOST_HANA_CHECK(hana::equal( 50 hana::mult(a, b), 51 hana::mult(b, a) 52 )); 53 54 only_when_(hana::not_equal(b, zero<D>()), 55 hana::make_lazy([](auto a, auto b) { 56 BOOST_HANA_CHECK(hana::equal( 57 hana::plus( 58 hana::mult(hana::div(a, b), b), 59 hana::mod(a, b) 60 ), 61 a 62 )); 63 64 BOOST_HANA_CHECK(hana::equal( 65 hana::mod(zero<D>(), b), 66 zero<D>() 67 )); 68 })(a, b)); 69 70 }); 71 } 72 }; 73 74 template <typename C> 75 struct TestEuclideanRing<C, when<Constant<C>::value>> 76 : TestEuclideanRing<C, laws> 77 { 78 template <typename Xs> TestEuclideanRingboost::hana::test::TestEuclideanRing79 TestEuclideanRing(Xs xs) : TestEuclideanRing<C, laws>{xs} { __anon93b5488e0402boost::hana::test::TestEuclideanRing80 foreach2(xs, [](auto x, auto y) { 81 only_when_(hana::not_equal(zero<C>(), y), 82 hana::make_lazy([](auto x, auto y) { 83 BOOST_HANA_CHECK(hana::equal( 84 hana::div(hana::value(x), hana::value(y)), 85 hana::value(hana::div(x, y)) 86 )); 87 88 BOOST_HANA_CHECK(hana::equal( 89 hana::mod(hana::value(x), hana::value(y)), 90 hana::value(hana::mod(x, y)) 91 )); 92 93 })(x, y)); 94 }); 95 } 96 }; 97 }}} // end namespace boost::hana::test 98 99 #endif // !BOOST_HANA_TEST_LAWS_EUCLIDEAN_RING_HPP 100