• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CONSTANT_HPP
6 #define BOOST_HANA_TEST_LAWS_CONSTANT_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/concept/logical.hpp>
14 
15 #include <laws/base.hpp>
16 #include <laws/comparable.hpp>
17 #include <laws/euclidean_ring.hpp>
18 #include <laws/group.hpp>
19 #include <laws/logical.hpp>
20 #include <laws/monoid.hpp>
21 #include <laws/orderable.hpp>
22 #include <laws/ring.hpp>
23 
24 #include <type_traits>
25 
26 
27 namespace boost { namespace hana { namespace test {
28     template <typename C, typename = when<true>>
29     struct TestConstant {
30         using T = typename C::value_type;
31 
32         template <typename X>
33         struct wrap_arbitrary_constant {
34             static constexpr bool value = boost::hana::value<X>();
35             using hana_tag = detail::CanonicalConstant<T>;
36         };
37 
38         template <typename Xs, typename Convertibles>
TestConstantboost::hana::test::TestConstant39         TestConstant(Xs xs, Convertibles types) {
40             hana::for_each(xs, [](auto x) {
41                 static_assert(Constant<decltype(x)>{}, "");
42             });
43 
44             hana::for_each(xs, hana::capture(types)([](auto types, auto c) {
45 
46                 // constexpr-ness of hana::value(c)
47                 constexpr auto must_be_constexpr1 = hana::value(c);
48                 constexpr auto must_be_constexpr2 = hana::value<decltype(c)>();
49                 (void)must_be_constexpr1;
50                 (void)must_be_constexpr2;
51 
52                 // consistency of C::value_type
53                 static_assert(std::is_same<
54                     T,
55                     tag_of_t<decltype(hana::value(c))>
56                 >{}, "");
57 
58                 // equivalence of value_of(c) and value<decltype(c)>
59                 BOOST_HANA_CHECK(hana::equal(
60                     hana::value_of(c),
61                     hana::value<decltype(c)>()
62                 ));
63 
64                 // equivalence of value<decltype(c)>() and value(c)
65                 BOOST_HANA_CHECK(hana::equal(
66                     hana::value<decltype(c)>(),
67                     hana::value(c)
68                 ));
69 
70                 // conversion from an arbitrary Constant
71                 (void)to<C>(wrap_arbitrary_constant<decltype(c)>{});
72                 static_assert(is_embedded<detail::CanonicalConstant<T>, C>{}, "");
73 
74                 hana::for_each(types, hana::capture(c)([](auto c, auto u) {
75                     using U = typename decltype(u)::type;
76 
77                     // conversion to something to which the underlying data
78                     // type can be converted.
79                     BOOST_HANA_CHECK(equal(
80                         to<U>(c),
81                         make<U>(hana::value(c))
82                     ));
83                     static_assert(is_embedded<C, U>::value ^iff^ is_embedded<T, U>::value, "");
84 
85                     // common data type
86                     static_assert(std::is_same<
87                         common_t<C, detail::CanonicalConstant<U>>,
88                         detail::CanonicalConstant<common_t<T, U>>
89                     >{}, "");
90 
91                     static_assert(std::is_same<
92                         common_t<detail::CanonicalConstant<U>, C>,
93                         detail::CanonicalConstant<common_t<T, U>>
94                     >{}, "");
95 
96                     static_assert(std::is_same<
97                         common_t<C, U>,
98                         common_t<typename C::value_type, U>
99                     >{}, "");
100                 }));
101             }));
102         }
103     };
104 }}} // end namespace boost::hana::test
105 
106 #endif // !BOOST_HANA_TEST_LAWS_CONSTANT_HPP
107