123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- // 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_ORDERABLE_HPP
- #define BOOST_HANA_TEST_LAWS_ORDERABLE_HPP
- #include <boost/hana/and.hpp>
- #include <boost/hana/assert.hpp>
- #include <boost/hana/bool.hpp>
- #include <boost/hana/concept/constant.hpp>
- #include <boost/hana/concept/orderable.hpp>
- #include <boost/hana/concept/product.hpp>
- #include <boost/hana/concept/sequence.hpp>
- #include <boost/hana/core/when.hpp>
- #include <boost/hana/first.hpp>
- #include <boost/hana/greater.hpp>
- #include <boost/hana/greater_equal.hpp>
- #include <boost/hana/lazy.hpp>
- #include <boost/hana/less.hpp>
- #include <boost/hana/less_equal.hpp>
- #include <boost/hana/not.hpp>
- #include <boost/hana/or.hpp>
- #include <boost/hana/ordering.hpp>
- #include <boost/hana/second.hpp>
- #include <boost/hana/value.hpp>
- #include <laws/base.hpp>
- namespace boost { namespace hana { namespace test {
- template <typename T, typename = when<true>>
- struct TestOrderable : TestOrderable<T, laws> {
- using TestOrderable<T, laws>::TestOrderable;
- };
- template <typename T>
- struct TestOrderable<T, laws> {
- template <typename Xs>
- TestOrderable(Xs xs) {
- hana::for_each(xs, [](auto x) {
- static_assert(Orderable<decltype(x)>{}, "");
- });
- foreach2(xs, [](auto a, auto b) {
- // antisymmetry
- BOOST_HANA_CHECK(
- hana::and_(hana::less_equal(a, b), hana::less_equal(b, a))
- ^implies^ hana::equal(a, b)
- );
- // totality
- BOOST_HANA_CHECK(
- hana::or_(hana::less_equal(a, b), hana::less_equal(b, a))
- );
- // other methods in terms of `less_equal`
- BOOST_HANA_CHECK(
- hana::less(a, b) ^iff^ hana::not_(hana::less_equal(b, a))
- );
- BOOST_HANA_CHECK(
- hana::greater(a, b) ^iff^ hana::less(b, a)
- );
- BOOST_HANA_CHECK(
- hana::greater_equal(a, b) ^iff^ hana::not_(hana::less(a, b))
- );
- // less.than & al.
- BOOST_HANA_CHECK(hana::less.than(a)(b) ^iff^ hana::less(b, a));
- BOOST_HANA_CHECK(hana::greater.than(a)(b) ^iff^ hana::greater(b, a));
- BOOST_HANA_CHECK(hana::less_equal.than(a)(b) ^iff^ hana::less_equal(b, a));
- BOOST_HANA_CHECK(hana::greater_equal.than(a)(b) ^iff^ hana::greater_equal(b, a));
- // ordering
- _injection<0> f{}; // test::_injection is also monotonic
- BOOST_HANA_CHECK(
- hana::ordering(f)(a, b) ^iff^ hana::less(f(a), f(b))
- );
- });
- // transitivity
- foreach3(xs, [](auto a, auto b, auto c) {
- BOOST_HANA_CHECK(
- hana::and_(hana::less_equal(a, b), hana::less_equal(b, c))
- ^implies^ hana::less_equal(a, c)
- );
- });
- }
- };
- template <typename C>
- struct TestOrderable<C, when<Constant<C>::value>>
- : TestOrderable<C, laws>
- {
- template <typename Xs>
- TestOrderable(Xs xs) : TestOrderable<C, laws>{xs} {
- foreach2(xs, [](auto a, auto b) {
- BOOST_HANA_CHECK(
- hana::value(hana::less(a, b)) ^iff^
- hana::less(hana::value(a), hana::value(b))
- );
- });
- }
- };
- template <typename P>
- struct TestOrderable<P, when<Product<P>::value>>
- : TestOrderable<P, laws>
- {
- template <typename Products>
- TestOrderable(Products products)
- : TestOrderable<P, laws>{products}
- {
- foreach2(products, [](auto x, auto y) {
- BOOST_HANA_CHECK(
- hana::less(x, y) ^iff^
- hana::or_(
- hana::less(hana::first(x), hana::first(y)),
- hana::and_(
- hana::equal(hana::first(x), hana::first(y)),
- hana::less(hana::second(x), hana::second(y))
- )
- )
- );
- });
- }
- };
- template <typename S>
- struct TestOrderable<S, when<Sequence<S>::value>>
- : TestOrderable<S, laws>
- {
- struct invalid { };
- template <typename Xs>
- TestOrderable(Xs xs) : TestOrderable<S, laws>{xs} {
- constexpr auto list = make<S>;
- //////////////////////////////////////////////////////////////////
- // less
- //////////////////////////////////////////////////////////////////
- BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
- list(),
- list()
- )));
- BOOST_HANA_CONSTANT_CHECK(hana::less(
- list(),
- list(invalid{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
- list(invalid{}),
- list()
- )));
- BOOST_HANA_CONSTANT_CHECK(hana::less(
- list(ct_ord<0>{}),
- list(ct_ord<7>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
- list(ct_ord<1>{}),
- list(ct_ord<0>{})
- )));
- BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less(
- list(ct_ord<0>{}, ct_ord<1>{}, ct_ord<8>{}),
- list(ct_ord<0>{}, ct_ord<1>{})
- )));
- BOOST_HANA_CONSTANT_CHECK(hana::less(
- list(ct_ord<0>{}, ct_ord<0>{}, ct_ord<8>{}),
- list(ct_ord<0>{}, ct_ord<1>{})
- ));
- }
- };
- }}} // end namespace boost::hana::test
- #endif // !BOOST_HANA_TEST_LAWS_ORDERABLE_HPP
|