mirror of
https://github.com/boostorg/hana.git
synced 2026-02-02 08:52:11 +00:00
280 lines
8.2 KiB
C++
280 lines
8.2 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 <test/cnumeric.hpp>
|
|
|
|
#include <boost/hana/assert.hpp>
|
|
#include <boost/hana/comparable.hpp>
|
|
#include <boost/hana/functional/curry.hpp>
|
|
#include <boost/hana/tuple.hpp>
|
|
#include <boost/hana/type.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>
|
|
using namespace boost::hana;
|
|
|
|
|
|
struct invalid { };
|
|
using test::ct_eq;
|
|
|
|
int main() {
|
|
auto ints = make<Tuple>(
|
|
test::cnumeric<int, -3>,
|
|
test::cnumeric<int, 0>,
|
|
test::cnumeric<int, 1>,
|
|
test::cnumeric<int, 2>,
|
|
test::cnumeric<int, 3>
|
|
);
|
|
(void)ints;
|
|
|
|
#if BOOST_HANA_TEST_PART == 1
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Constant
|
|
//////////////////////////////////////////////////////////////////////////
|
|
{
|
|
// value
|
|
static_assert(value(test::cnumeric<int, 0>) == 0, "");
|
|
static_assert(value(test::cnumeric<int, 1>) == 1, "");
|
|
|
|
// laws
|
|
test::TestConstant<test::CNumeric<int>>{ints, tuple_t<int, long, long long>};
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Enumerable, Monoid, Group, Ring, IntegralDomain
|
|
//////////////////////////////////////////////////////////////////////////
|
|
{
|
|
test::TestEnumerable<test::CNumeric<int>>{ints};
|
|
test::TestMonoid<test::CNumeric<int>>{ints};
|
|
test::TestGroup<test::CNumeric<int>>{ints};
|
|
test::TestRing<test::CNumeric<int>>{ints};
|
|
test::TestIntegralDomain<test::CNumeric<int>>{ints};
|
|
}
|
|
|
|
#elif BOOST_HANA_TEST_PART == 2
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Comparable
|
|
//////////////////////////////////////////////////////////////////////////
|
|
test::TestComparable<test::CNumeric<int>>{ints};
|
|
|
|
#elif BOOST_HANA_TEST_PART == 3
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Orderable
|
|
//////////////////////////////////////////////////////////////////////////
|
|
test::TestOrderable<test::CNumeric<int>>{ints};
|
|
|
|
#elif BOOST_HANA_TEST_PART == 4
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Logical
|
|
//////////////////////////////////////////////////////////////////////////
|
|
{
|
|
constexpr auto true_ = test::cnumeric<bool, true>;
|
|
constexpr auto false_ = test::cnumeric<bool, false>;
|
|
|
|
// not_
|
|
{
|
|
BOOST_HANA_CONSTANT_CHECK(equal(not_(true_), false_));
|
|
}
|
|
|
|
// and_
|
|
{
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(true_),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(false_),
|
|
false_
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(true_, true_),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(true_, false_),
|
|
false_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(false_, invalid{}),
|
|
false_
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(true_, true_, true_),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(true_, true_, false_),
|
|
false_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(true_, false_, invalid{}),
|
|
false_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
and_(false_, invalid{}, invalid{}),
|
|
false_
|
|
));
|
|
}
|
|
|
|
// or_
|
|
{
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(true_),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(false_),
|
|
false_
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(false_, false_),
|
|
false_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(false_, true_),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(true_, invalid{}),
|
|
true_
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(false_, false_, false_),
|
|
false_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(false_, false_, true_),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(false_, true_, invalid{}),
|
|
true_
|
|
));
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
or_(true_, invalid{}, invalid{}),
|
|
true_
|
|
));
|
|
}
|
|
|
|
// if_
|
|
{
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
if_(true_, ct_eq<3>{}, ct_eq<4>{}), ct_eq<3>{}
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
if_(false_, ct_eq<3>{}, ct_eq<4>{}), ct_eq<4>{}
|
|
));
|
|
}
|
|
|
|
// eval_if
|
|
{
|
|
auto t = [](auto) { return ct_eq<2>{}; };
|
|
auto e = [](auto) { return ct_eq<3>{}; };
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
eval_if(true_, t, invalid{}), ct_eq<2>{}
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
eval_if(false_, invalid{}, e), ct_eq<3>{}
|
|
));
|
|
}
|
|
|
|
// while_
|
|
{
|
|
test::_injection<0> f{};
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
while_(not_equal.to(ct_eq<0>{}), ct_eq<0>{}, invalid{}),
|
|
ct_eq<0>{}
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
while_(not_equal.to(f(ct_eq<0>{})), ct_eq<0>{}, f),
|
|
f(ct_eq<0>{})
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
while_(not_equal.to(f(f(ct_eq<0>{}))), ct_eq<0>{}, f),
|
|
f(f(ct_eq<0>{}))
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
while_(not_equal.to(f(f(f(ct_eq<0>{})))), ct_eq<0>{}, f),
|
|
f(f(f(ct_eq<0>{})))
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
while_(not_equal.to(f(f(f(f(ct_eq<0>{}))))), ct_eq<0>{}, f),
|
|
f(f(f(f(ct_eq<0>{}))))
|
|
));
|
|
|
|
// Make sure it can be called with an lvalue state:
|
|
auto state = ct_eq<0>{};
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
while_(not_equal.to(f(f(f(f(ct_eq<0>{}))))), state, f),
|
|
f(f(f(f(ct_eq<0>{}))))
|
|
));
|
|
}
|
|
|
|
// until
|
|
{
|
|
test::_injection<0> f{};
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
until(equal.to(ct_eq<0>{}), ct_eq<0>{}, invalid{}),
|
|
ct_eq<0>{}
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
until(equal.to(f(ct_eq<0>{})), ct_eq<0>{}, f),
|
|
f(ct_eq<0>{})
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
until(equal.to(f(f(ct_eq<0>{}))), ct_eq<0>{}, f),
|
|
f(f(ct_eq<0>{}))
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
until(equal.to(f(f(f(ct_eq<0>{})))), ct_eq<0>{}, f),
|
|
f(f(f(ct_eq<0>{})))
|
|
));
|
|
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
until(equal.to(f(f(f(f(ct_eq<0>{}))))), ct_eq<0>{}, f),
|
|
f(f(f(f(ct_eq<0>{}))))
|
|
));
|
|
|
|
// Make sure it can be called with an lvalue state:
|
|
auto state = ct_eq<0>{};
|
|
BOOST_HANA_CONSTANT_CHECK(equal(
|
|
until(equal.to(f(f(f(f(ct_eq<0>{}))))), state, f),
|
|
f(f(f(f(ct_eq<0>{}))))
|
|
));
|
|
}
|
|
|
|
// laws
|
|
test::TestLogical<test::CNumeric<bool>>{make<Tuple>(
|
|
test::cnumeric<bool, true>, test::cnumeric<bool, false>
|
|
)};
|
|
}
|
|
#endif
|
|
}
|