107 lines
3.8 KiB
C++
107 lines
3.8 KiB
C++
// Copyright Louis Dionne 2013-2017
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
|
|
|
#ifndef BOOST_HANA_TEST_LAWS_CONSTANT_HPP
|
|
#define BOOST_HANA_TEST_LAWS_CONSTANT_HPP
|
|
|
|
#include <boost/hana/assert.hpp>
|
|
#include <boost/hana/bool.hpp>
|
|
#include <boost/hana/concept/comparable.hpp>
|
|
#include <boost/hana/core/when.hpp>
|
|
#include <boost/hana/functional/capture.hpp>
|
|
#include <boost/hana/concept/logical.hpp>
|
|
|
|
#include <laws/base.hpp>
|
|
#include <laws/comparable.hpp>
|
|
#include <laws/euclidean_ring.hpp>
|
|
#include <laws/group.hpp>
|
|
#include <laws/logical.hpp>
|
|
#include <laws/monoid.hpp>
|
|
#include <laws/orderable.hpp>
|
|
#include <laws/ring.hpp>
|
|
|
|
#include <type_traits>
|
|
|
|
|
|
namespace boost { namespace hana { namespace test {
|
|
template <typename C, typename = when<true>>
|
|
struct TestConstant {
|
|
using T = typename C::value_type;
|
|
|
|
template <typename X>
|
|
struct wrap_arbitrary_constant {
|
|
static constexpr bool value = boost::hana::value<X>();
|
|
using hana_tag = detail::CanonicalConstant<T>;
|
|
};
|
|
|
|
template <typename Xs, typename Convertibles>
|
|
TestConstant(Xs xs, Convertibles types) {
|
|
hana::for_each(xs, [](auto x) {
|
|
static_assert(Constant<decltype(x)>{}, "");
|
|
});
|
|
|
|
hana::for_each(xs, hana::capture(types)([](auto types, auto c) {
|
|
|
|
// constexpr-ness of hana::value(c)
|
|
constexpr auto must_be_constexpr1 = hana::value(c);
|
|
constexpr auto must_be_constexpr2 = hana::value<decltype(c)>();
|
|
(void)must_be_constexpr1;
|
|
(void)must_be_constexpr2;
|
|
|
|
// consistency of C::value_type
|
|
static_assert(std::is_same<
|
|
T,
|
|
tag_of_t<decltype(hana::value(c))>
|
|
>{}, "");
|
|
|
|
// equivalence of value_of(c) and value<decltype(c)>
|
|
BOOST_HANA_CHECK(hana::equal(
|
|
hana::value_of(c),
|
|
hana::value<decltype(c)>()
|
|
));
|
|
|
|
// equivalence of value<decltype(c)>() and value(c)
|
|
BOOST_HANA_CHECK(hana::equal(
|
|
hana::value<decltype(c)>(),
|
|
hana::value(c)
|
|
));
|
|
|
|
// conversion from an arbitrary Constant
|
|
(void)to<C>(wrap_arbitrary_constant<decltype(c)>{});
|
|
static_assert(is_embedded<detail::CanonicalConstant<T>, C>{}, "");
|
|
|
|
hana::for_each(types, hana::capture(c)([](auto c, auto u) {
|
|
using U = typename decltype(u)::type;
|
|
|
|
// conversion to something to which the underlying data
|
|
// type can be converted.
|
|
BOOST_HANA_CHECK(equal(
|
|
to<U>(c),
|
|
make<U>(hana::value(c))
|
|
));
|
|
static_assert(is_embedded<C, U>::value ^iff^ is_embedded<T, U>::value, "");
|
|
|
|
// common data type
|
|
static_assert(std::is_same<
|
|
common_t<C, detail::CanonicalConstant<U>>,
|
|
detail::CanonicalConstant<common_t<T, U>>
|
|
>{}, "");
|
|
|
|
static_assert(std::is_same<
|
|
common_t<detail::CanonicalConstant<U>, C>,
|
|
detail::CanonicalConstant<common_t<T, U>>
|
|
>{}, "");
|
|
|
|
static_assert(std::is_same<
|
|
common_t<C, U>,
|
|
common_t<typename C::value_type, U>
|
|
>{}, "");
|
|
}));
|
|
}));
|
|
}
|
|
};
|
|
}}} // end namespace boost::hana::test
|
|
|
|
#endif // !BOOST_HANA_TEST_LAWS_CONSTANT_HPP
|