ring.hpp 3.9 KB

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