comparable.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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_COMPARABLE_HPP
  5. #define BOOST_HANA_TEST_LAWS_COMPARABLE_HPP
  6. #include <boost/hana/and.hpp>
  7. #include <boost/hana/assert.hpp>
  8. #include <boost/hana/bool.hpp>
  9. #include <boost/hana/comparing.hpp>
  10. #include <boost/hana/concept/comparable.hpp>
  11. #include <boost/hana/concept/constant.hpp>
  12. #include <boost/hana/concept/product.hpp>
  13. #include <boost/hana/concept/sequence.hpp>
  14. #include <boost/hana/core/make.hpp>
  15. #include <boost/hana/core/when.hpp>
  16. #include <boost/hana/equal.hpp>
  17. #include <boost/hana/first.hpp>
  18. #include <boost/hana/for_each.hpp>
  19. #include <boost/hana/lazy.hpp>
  20. #include <boost/hana/not_equal.hpp>
  21. #include <boost/hana/second.hpp>
  22. #include <boost/hana/value.hpp>
  23. #include <laws/base.hpp>
  24. namespace boost { namespace hana { namespace test {
  25. template <typename T, typename = hana::when<true>>
  26. struct TestComparable : TestComparable<T, laws> {
  27. using TestComparable<T, laws>::TestComparable;
  28. };
  29. template <typename T>
  30. struct TestComparable<T, laws> {
  31. template <typename Xs>
  32. TestComparable(Xs xs) {
  33. hana::for_each(xs, [](auto x) {
  34. static_assert(hana::Comparable<decltype(x)>{}, "");
  35. });
  36. foreach2(xs, [](auto a, auto b) {
  37. // reflexivity
  38. BOOST_HANA_CHECK(
  39. hana::equal(a, a)
  40. );
  41. // symmetry
  42. BOOST_HANA_CHECK(
  43. hana::equal(a, b) ^implies^ hana::equal(b, a)
  44. );
  45. // `not_equal` is the negation of `equal`
  46. BOOST_HANA_CHECK(
  47. hana::not_equal(a, b) ^iff^ hana::not_(hana::equal(a, b))
  48. );
  49. // equal.to and not_equal.to
  50. BOOST_HANA_CHECK(
  51. hana::equal.to(a)(b) ^iff^ hana::equal(a, b)
  52. );
  53. BOOST_HANA_CHECK(
  54. hana::not_equal.to(a)(b) ^iff^ hana::not_equal(a, b)
  55. );
  56. // comparing
  57. _injection<0> f{};
  58. BOOST_HANA_CHECK(
  59. hana::comparing(f)(a, b) ^iff^ hana::equal(f(a), f(b))
  60. );
  61. });
  62. // transitivity
  63. foreach3(xs, [](auto a, auto b, auto c) {
  64. BOOST_HANA_CHECK(
  65. hana::and_(hana::equal(a, b), hana::equal(b, c))
  66. ^implies^ hana::equal(a, c)
  67. );
  68. });
  69. }
  70. };
  71. template <typename C>
  72. struct TestComparable<C, when<Constant<C>::value>>
  73. : TestComparable<C, laws>
  74. {
  75. template <typename Xs>
  76. TestComparable(Xs xs) : TestComparable<C, laws>{xs} {
  77. foreach2(xs, [](auto a, auto b) {
  78. BOOST_HANA_CHECK(
  79. hana::value(hana::equal(a, b)) ^iff^
  80. hana::equal(hana::value(a), hana::value(b))
  81. );
  82. });
  83. }
  84. };
  85. template <typename P>
  86. struct TestComparable<P, when<Product<P>::value>>
  87. : TestComparable<P, laws>
  88. {
  89. template <typename Products>
  90. TestComparable(Products products) : TestComparable<P, laws>{products} {
  91. foreach2(products, [](auto x, auto y) {
  92. BOOST_HANA_CHECK(
  93. hana::equal(x, y) ^iff^
  94. hana::and_(
  95. hana::equal(hana::first(x), hana::first(y)),
  96. hana::equal(hana::second(x), hana::second(y))
  97. )
  98. );
  99. });
  100. }
  101. };
  102. template <typename S>
  103. struct TestComparable<S, when<Sequence<S>::value>>
  104. : TestComparable<S, laws>
  105. {
  106. template <int i>
  107. using x = _constant<i>;
  108. template <typename Xs>
  109. TestComparable(Xs xs) : TestComparable<S, laws>{xs} {
  110. constexpr auto list = make<S>;
  111. //////////////////////////////////////////////////////////////////
  112. // equal
  113. //////////////////////////////////////////////////////////////////
  114. BOOST_HANA_CONSTANT_CHECK(hana::equal(
  115. list(),
  116. list()
  117. ));
  118. BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
  119. list(x<0>{}),
  120. list()
  121. )));
  122. BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
  123. list(),
  124. list(x<0>{})
  125. )));
  126. BOOST_HANA_CONSTANT_CHECK(hana::equal(
  127. list(x<0>{}),
  128. list(x<0>{})
  129. ));
  130. BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
  131. list(x<0>{}, x<1>{}),
  132. list(x<0>{})
  133. )));
  134. BOOST_HANA_CONSTANT_CHECK(hana::equal(
  135. list(x<0>{}, x<1>{}),
  136. list(x<0>{}, x<1>{})
  137. ));
  138. BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
  139. list(x<0>{}, x<1>{}, x<2>{}, x<3>{}),
  140. list(x<0>{}, x<1>{}, x<2>{}, x<4>{})
  141. )));
  142. }
  143. };
  144. }}} // end namespace boost::hana::test
  145. #endif // !BOOST_HANA_TEST_LAWS_COMPARABLE_HPP