hashable.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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_HASHABLE_HPP
  5. #define BOOST_HANA_TEST_LAWS_HASHABLE_HPP
  6. #include <boost/hana/assert.hpp>
  7. #include <boost/hana/bool.hpp>
  8. #include <boost/hana/concept/hashable.hpp>
  9. #include <boost/hana/core/default.hpp>
  10. #include <boost/hana/core/tag_of.hpp>
  11. #include <boost/hana/core/when.hpp>
  12. #include <boost/hana/equal.hpp>
  13. #include <boost/hana/for_each.hpp>
  14. #include <boost/hana/hash.hpp>
  15. #include <boost/hana/if.hpp>
  16. #include <laws/base.hpp>
  17. namespace boost { namespace hana { namespace test {
  18. template <typename G, typename = when<true>>
  19. struct TestHashable : TestHashable<G, laws> {
  20. using TestHashable<G, laws>::TestHashable;
  21. };
  22. template <typename H>
  23. struct TestHashable<H, laws> {
  24. template <typename Xs>
  25. TestHashable(Xs xs) {
  26. hana::for_each(xs, [](auto x) {
  27. static_assert(Hashable<decltype(x)>{}, "");
  28. });
  29. hana::for_each(xs, [&](auto const& x) {
  30. hana::for_each(xs, [&](auto const& y) {
  31. using X = hana::tag_of_t<decltype(x)>;
  32. using Y = hana::tag_of_t<decltype(y)>;
  33. constexpr bool comparable = !hana::is_default<
  34. hana::equal_impl<X, Y>
  35. >::value;
  36. hana::if_(hana::bool_c<comparable>,
  37. [](auto const& x, auto const& y) {
  38. BOOST_HANA_CHECK(
  39. hana::equal(x, y)
  40. ^implies^
  41. hana::equal(hana::hash(x), hana::hash(y))
  42. );
  43. },
  44. [](auto...) { }
  45. )(x, y);
  46. });
  47. });
  48. }
  49. };
  50. }}} // end namespace boost::hana::test
  51. #endif // !BOOST_HANA_TEST_LAWS_HASHABLE_HPP