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