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)
5 #ifndef BOOST_HANA_TEST_LAWS_CONSTANT_HPP
6 #define BOOST_HANA_TEST_LAWS_CONSTANT_HPP
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>
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>
24 #include <type_traits>
27 namespace boost { namespace hana { namespace test {
28 template <typename C, typename = when<true>>
30 using T = typename C::value_type;
33 struct wrap_arbitrary_constant {
34 static constexpr bool value = boost::hana::value<X>();
35 using hana_tag = detail::CanonicalConstant<T>;
38 template <typename Xs, typename Convertibles>
39 TestConstant(Xs xs, Convertibles types) {
40 hana::for_each(xs, [](auto x) {
41 static_assert(Constant<decltype(x)>{}, "");
44 hana::for_each(xs, hana::capture(types)([](auto types, auto c) {
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;
52 // consistency of C::value_type
53 static_assert(std::is_same<
55 tag_of_t<decltype(hana::value(c))>
58 // equivalence of value_of(c) and value<decltype(c)>
59 BOOST_HANA_CHECK(hana::equal(
61 hana::value<decltype(c)>()
64 // equivalence of value<decltype(c)>() and value(c)
65 BOOST_HANA_CHECK(hana::equal(
66 hana::value<decltype(c)>(),
70 // conversion from an arbitrary Constant
71 (void)to<C>(wrap_arbitrary_constant<decltype(c)>{});
72 static_assert(is_embedded<detail::CanonicalConstant<T>, C>{}, "");
74 hana::for_each(types, hana::capture(c)([](auto c, auto u) {
75 using U = typename decltype(u)::type;
77 // conversion to something to which the underlying data
78 // type can be converted.
79 BOOST_HANA_CHECK(equal(
81 make<U>(hana::value(c))
83 static_assert(is_embedded<C, U>::value ^iff^ is_embedded<T, U>::value, "");
86 static_assert(std::is_same<
87 common_t<C, detail::CanonicalConstant<U>>,
88 detail::CanonicalConstant<common_t<T, U>>
91 static_assert(std::is_same<
92 common_t<detail::CanonicalConstant<U>, C>,
93 detail::CanonicalConstant<common_t<T, U>>
96 static_assert(std::is_same<
98 common_t<typename C::value_type, U>
104 }}} // end namespace boost::hana::test
106 #endif // !BOOST_HANA_TEST_LAWS_CONSTANT_HPP