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