2
0
mirror of https://github.com/boostorg/hana.git synced 2026-02-02 08:52:11 +00:00
Files
hana/test/integral_constant.cpp

261 lines
9.4 KiB
C++

/*
@copyright Louis Dionne 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/assert.hpp>
#include <boost/hana/core/datatype.hpp>
#include <boost/hana/tuple.hpp>
#include <laws/base.hpp>
#include <laws/comparable.hpp>
#include <laws/constant.hpp>
#include <laws/enumerable.hpp>
#include <laws/group.hpp>
#include <laws/integral_domain.hpp>
#include <laws/logical.hpp>
#include <laws/monoid.hpp>
#include <laws/orderable.hpp>
#include <laws/ring.hpp>
#include <cstddef>
#include <type_traits>
using namespace boost::hana;
int main() {
auto ints = make<Tuple>(
int_<-10>, int_<-2>, int_<0>, int_<1>, int_<3>, int_<4>
);
(void)ints;
auto bools = make<Tuple>(true_, false_);
(void)bools;
#if BOOST_HANA_TEST_PART == 1
//////////////////////////////////////////////////////////////////////////
// IntegralConstant's API (like std::integral_constant)
//////////////////////////////////////////////////////////////////////////
{
// operator()
static_assert(size_t<0>() == 0, "");
static_assert(size_t<1>() == 1, "");
static_assert(int_<-3>() == -3, "");
// decltype(operator())
static_assert(std::is_same<decltype(size_t<0>()), std::size_t>{}, "");
static_assert(std::is_same<decltype(int_<-3>()), int>{}, "");
// conversions
constexpr std::size_t a = size_t<0>, b = size_t<1>;
static_assert(a == 0 && b == 1, "");
constexpr int c = int_<0>, d = int_<-3>;
static_assert(c == 0 && d == -3, "");
// nested ::value
static_assert(decltype(int_<1>)::value == 1, "");
// nested ::type
static_assert(std::is_same<
decltype(int_<1>)::type,
std::remove_cv_t<decltype(int_<1>)>
>{}, "");
// nested ::value_type
static_assert(std::is_same<decltype(int_<1>)::value_type, int>{}, "");
}
//////////////////////////////////////////////////////////////////////////
// Make sure we can inherit _integral_constant and retain the same
// data type.
//////////////////////////////////////////////////////////////////////////
{
struct derived : _integral_constant<int, 10> { };
static_assert(std::is_same<datatype_t<derived>, IntegralConstant<int>>{}, "");
}
//////////////////////////////////////////////////////////////////////////
// Extensions to std::integral_constant
//////////////////////////////////////////////////////////////////////////
{
// times member function (the other ones are tested in the examples)
{
int counter = 0;
int_<3>.times([&] { ++counter; });
BOOST_HANA_RUNTIME_CHECK(counter == 3);
}
// Arithmetic operators
{
BOOST_HANA_CONSTANT_CHECK(+int_<1> == int_<1>);
BOOST_HANA_CONSTANT_CHECK(-int_<1> == int_<-1>);
BOOST_HANA_CONSTANT_CHECK(int_<1> + int_<2> == int_<3>);
BOOST_HANA_CONSTANT_CHECK(int_<1> - int_<2> == int_<-1>);
BOOST_HANA_CONSTANT_CHECK(int_<3> * int_<2> == int_<6>);
BOOST_HANA_CONSTANT_CHECK(int_<6> / int_<3> == int_<2>);
BOOST_HANA_CONSTANT_CHECK(int_<6> % int_<4> == int_<2>);
BOOST_HANA_CONSTANT_CHECK(~int_<6> == int_<~6>);
BOOST_HANA_CONSTANT_CHECK((int_<6> & int_<3>) == int_<6 & 3>);
BOOST_HANA_CONSTANT_CHECK((int_<4> | int_<2>) == int_<4 | 2>);
BOOST_HANA_CONSTANT_CHECK((int_<6> ^ int_<3>) == int_<6 ^ 3>);
BOOST_HANA_CONSTANT_CHECK((int_<6> << int_<3>) == int_<(6 << 3)>);
BOOST_HANA_CONSTANT_CHECK((int_<6> >> int_<3>) == int_<(6 >> 3)>);
}
// Comparison operators
{
BOOST_HANA_CONSTANT_CHECK(int_<0> == int_<0>);
BOOST_HANA_CONSTANT_CHECK(int_<1> != int_<0>);
BOOST_HANA_CONSTANT_CHECK(int_<0> < int_<1>);
BOOST_HANA_CONSTANT_CHECK(int_<0> <= int_<1>);
BOOST_HANA_CONSTANT_CHECK(int_<0> <= int_<0>);
BOOST_HANA_CONSTANT_CHECK(int_<1> > int_<0>);
BOOST_HANA_CONSTANT_CHECK(int_<1> >= int_<0>);
BOOST_HANA_CONSTANT_CHECK(int_<0> >= int_<0>);
}
// Logical operators
{
BOOST_HANA_CONSTANT_CHECK(int_<3> || int_<0>);
BOOST_HANA_CONSTANT_CHECK(int_<3> && int_<1>);
BOOST_HANA_CONSTANT_CHECK(!int_<0>);
BOOST_HANA_CONSTANT_CHECK(!!int_<3>);
}
// Creation with user-defined literals
{
using namespace boost::hana::literals;
BOOST_HANA_CONSTANT_CHECK(0_c == llong<0>);
BOOST_HANA_CONSTANT_CHECK(1_c == llong<1>);
BOOST_HANA_CONSTANT_CHECK(12_c == llong<12>);
BOOST_HANA_CONSTANT_CHECK(123_c == llong<123>);
BOOST_HANA_CONSTANT_CHECK(1234567_c == llong<1234567>);
BOOST_HANA_CONSTANT_CHECK(-34_c == llong<-34>);
static_assert(std::is_same<
decltype(-1234_c)::value_type,
long long
>{}, "");
static_assert(-1234_c == -1234ll, "");
BOOST_HANA_CONSTANT_CHECK(-12_c < 0_c);
}
}
#elif BOOST_HANA_TEST_PART == 2
//////////////////////////////////////////////////////////////////////////
// Constant
//////////////////////////////////////////////////////////////////////////
{
// value
static_assert(value(integral_constant<int, 0>) == 0, "");
static_assert(value(integral_constant<int, 1>) == 1, "");
// laws
test::TestConstant<IntegralConstant<int>>{ints, tuple_t<int, long, long long>};
test::TestConstant<IntegralConstant<bool>>{bools, tuple_t<bool>};
}
#elif BOOST_HANA_TEST_PART == 3
//////////////////////////////////////////////////////////////////////////
// Enumerable, Monoid, Group
//////////////////////////////////////////////////////////////////////////
{
// operators
static_assert(has_operator<IntegralConstant<int>, decltype(plus)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(minus)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(negate)>{}, "");
// laws
test::TestEnumerable<IntegralConstant<int>>{ints};
test::TestMonoid<IntegralConstant<int>>{ints};
test::TestGroup<IntegralConstant<int>>{ints};
}
#elif BOOST_HANA_TEST_PART == 4
//////////////////////////////////////////////////////////////////////////
// Ring, IntegralDomain
//////////////////////////////////////////////////////////////////////////
{
// operators
static_assert(has_operator<IntegralConstant<int>, decltype(mult)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(quot)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(rem)>{}, "");
// laws
test::TestRing<IntegralConstant<int>>{ints};
test::TestIntegralDomain<IntegralConstant<int>>{ints};
}
#elif BOOST_HANA_TEST_PART == 5
//////////////////////////////////////////////////////////////////////////
// Logical
//////////////////////////////////////////////////////////////////////////
{
auto t = test::ct_eq<3>{};
auto e = test::ct_eq<4>{};
// eval_if
{
BOOST_HANA_CONSTANT_CHECK(equal(
eval_if(true_, always(t), always(e)),
t
));
BOOST_HANA_CONSTANT_CHECK(equal(
eval_if(false_, always(t), always(e)),
e
));
}
// not_
{
BOOST_HANA_CONSTANT_CHECK(equal(not_(true_), false_));
BOOST_HANA_CONSTANT_CHECK(equal(not_(false_), true_));
}
// operators
static_assert(has_operator<IntegralConstant<int>, decltype(not_)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(and_)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(or_)>{}, "");
// laws
auto ints = make<Tuple>(int_<-2>, int_<0>, int_<1>, int_<3>);
test::TestLogical<IntegralConstant<int>>{ints};
test::TestLogical<IntegralConstant<bool>>{bools};
}
#elif BOOST_HANA_TEST_PART == 6
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
{
// operators
static_assert(has_operator<IntegralConstant<int>, decltype(equal)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(not_equal)>{}, "");
// laws
test::TestComparable<IntegralConstant<int>>{ints};
}
#elif BOOST_HANA_TEST_PART == 7
//////////////////////////////////////////////////////////////////////////
// Orderable
//////////////////////////////////////////////////////////////////////////
{
// operators
static_assert(has_operator<IntegralConstant<int>, decltype(less)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(less_equal)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(greater)>{}, "");
static_assert(has_operator<IntegralConstant<int>, decltype(greater_equal)>{}, "");
// laws
test::TestOrderable<IntegralConstant<int>>{ints};
}
#endif
}