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_RING_HPP 6 #define BOOST_HANA_TEST_LAWS_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/monoid.hpp> 13 #include <boost/hana/concept/ring.hpp> 14 #include <boost/hana/core/when.hpp> 15 #include <boost/hana/equal.hpp> 16 #include <boost/hana/functional/capture.hpp> 17 #include <boost/hana/lazy.hpp> 18 #include <boost/hana/mult.hpp> 19 #include <boost/hana/not_equal.hpp> 20 #include <boost/hana/one.hpp> 21 #include <boost/hana/plus.hpp> 22 #include <boost/hana/power.hpp> 23 #include <boost/hana/value.hpp> 24 25 #include <laws/base.hpp> 26 27 28 namespace boost { namespace hana { namespace test { 29 template <typename R, typename = when<true>> 30 struct TestRing : TestRing<R, laws> { 31 using TestRing<R, laws>::TestRing; 32 }; 33 34 template <typename R> 35 struct TestRing<R, laws> { 36 template <typename Xs> TestRingboost::hana::test::TestRing37 TestRing(Xs xs) { 38 #ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 39 one<R>(); // force adding one<R>'s member function to pending temploid list 40 #endif 41 42 hana::for_each(xs, hana::capture(xs)([](auto xs, auto x) { 43 static_assert(Ring<decltype(x)>{}, ""); 44 45 foreach2(xs, hana::capture(x)([](auto x, auto y, auto z) { 46 // associativity 47 BOOST_HANA_CHECK(hana::equal( 48 hana::mult(x, hana::mult(y, z)), 49 hana::mult(hana::mult(x, y), z) 50 )); 51 52 // distributivity 53 BOOST_HANA_CHECK(hana::equal( 54 hana::mult(x, hana::plus(y, z)), 55 hana::plus(hana::mult(x, y), hana::mult(x, z)) 56 )); 57 })); 58 59 // right identity 60 BOOST_HANA_CHECK(hana::equal( 61 hana::mult(x, one<R>()), x 62 )); 63 64 // left identity 65 BOOST_HANA_CHECK(hana::equal( 66 hana::mult(one<R>(), x), x 67 )); 68 69 // power 70 BOOST_HANA_CHECK(hana::equal( 71 hana::power(x, int_c<0>), 72 one<R>() 73 )); 74 75 BOOST_HANA_CHECK(hana::equal( 76 hana::power(x, int_c<1>), 77 x 78 )); 79 80 BOOST_HANA_CHECK(hana::equal( 81 hana::power(x, int_c<2>), 82 hana::mult(x, x) 83 )); 84 85 BOOST_HANA_CHECK(hana::equal( 86 hana::power(x, int_c<3>), 87 hana::mult(hana::mult(x, x), x) 88 )); 89 90 BOOST_HANA_CHECK(hana::equal( 91 hana::power(x, int_c<4>), 92 hana::mult(hana::mult(hana::mult(x, x), x), x) 93 )); 94 95 BOOST_HANA_CHECK(hana::equal( 96 hana::power(x, int_c<5>), 97 hana::mult(hana::mult(hana::mult(hana::mult(x, x), x), x), x) 98 )); 99 100 })); 101 } 102 }; 103 104 template <typename C> 105 struct TestRing<C, when<Constant<C>::value>> 106 : TestRing<C, laws> 107 { 108 template <typename Xs> TestRingboost::hana::test::TestRing109 TestRing(Xs xs) : TestRing<C, laws>{xs} { 110 BOOST_HANA_CHECK(hana::equal( 111 hana::value(one<C>()), 112 one<typename C::value_type>() 113 )); 114 __anon4179c7050302boost::hana::test::TestRing115 foreach2(xs, [](auto x, auto y) { 116 BOOST_HANA_CHECK(hana::equal( 117 hana::mult(hana::value(x), hana::value(y)), 118 hana::value(hana::mult(x, y)) 119 )); 120 }); 121 } 122 }; 123 }}} // end namespace boost::hana::test 124 125 #endif // !BOOST_HANA_TEST_LAWS_RING_HPP 126