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_MONOID_HPP 6 #define BOOST_HANA_TEST_LAWS_MONOID_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/core/when.hpp> 12 #include <boost/hana/functional/capture.hpp> 13 #include <boost/hana/lazy.hpp> 14 #include <boost/hana/concept/monoid.hpp> 15 16 #include <laws/base.hpp> 17 18 19 namespace boost { namespace hana { namespace test { 20 template <typename M, typename = when<true>> 21 struct TestMonoid : TestMonoid<M, laws> { 22 using TestMonoid<M, laws>::TestMonoid; 23 }; 24 25 template <typename M> 26 struct TestMonoid<M, laws> { 27 template <typename Xs> TestMonoidboost::hana::test::TestMonoid28 TestMonoid(Xs xs) { 29 #ifdef BOOST_HANA_WORKAROUND_MSVC_DECLTYPEAUTO_RETURNTYPE_662735 30 zero<M>(); // force adding zero<M>'s member function to pending temploid list 31 #endif 32 33 hana::for_each(xs, hana::capture(xs)([](auto xs, auto a) { 34 static_assert(Monoid<decltype(a)>{}, ""); 35 36 // left identity 37 BOOST_HANA_CHECK(hana::equal( 38 hana::plus(zero<M>(), a), 39 a 40 )); 41 42 // right identity 43 BOOST_HANA_CHECK(hana::equal( 44 hana::plus(a, zero<M>()), 45 a 46 )); 47 48 hana::for_each(xs, 49 hana::capture(xs, a)([](auto xs, auto a, auto b) { 50 hana::for_each(xs, 51 hana::capture(a, b)([](auto a, auto b, auto c) { 52 // associativity 53 BOOST_HANA_CHECK(equal( 54 hana::plus(a, hana::plus(b, c)), 55 hana::plus(hana::plus(a, b), c) 56 )); 57 })); 58 })); 59 60 })); 61 } 62 }; 63 64 template <typename C> 65 struct TestMonoid<C, when<Constant<C>::value>> 66 : TestMonoid<C, laws> 67 { 68 template <typename Xs> TestMonoidboost::hana::test::TestMonoid69 TestMonoid(Xs xs) : TestMonoid<C, laws>{xs} { 70 71 BOOST_HANA_CHECK(hana::equal( 72 hana::value(zero<C>()), 73 zero<typename C::value_type>() 74 )); 75 __anon56faa87c0402boost::hana::test::TestMonoid76 foreach2(xs, [](auto x, auto y) { 77 BOOST_HANA_CHECK(hana::equal( 78 hana::plus(hana::value(x), hana::value(y)), 79 hana::value(hana::plus(x, y)) 80 )); 81 }); 82 } 83 }; 84 }}} // end namespace boost::hana::test 85 86 #endif // !BOOST_HANA_TEST_LAWS_MONOID_HPP 87