• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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