2
0
mirror of https://github.com/boostorg/hana.git synced 2026-01-23 05:32:13 +00:00
Files
hana/test/maybe.cpp
2015-02-01 10:35:17 -05:00

278 lines
7.6 KiB
C++

/*
@copyright Louis Dionne 2014
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/maybe.hpp>
#include <boost/hana/assert.hpp>
#include <boost/hana/bool.hpp>
#include <boost/hana/functional/always.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/tuple.hpp>
#include <boost/hana/type.hpp>
#include <test/auto/applicative.hpp>
#include <test/auto/base.hpp>
#include <test/auto/comparable.hpp>
#include <test/auto/foldable.hpp>
#include <test/auto/functor.hpp>
#include <test/auto/monad.hpp>
#include <test/auto/orderable.hpp>
#include <test/auto/searchable.hpp>
#include <test/auto/traversable.hpp>
#include <test/cnumeric.hpp>
#include <test/identity.hpp>
#include <test/injection.hpp>
using namespace boost::hana;
template <int i>
constexpr auto ord = test::cnumeric<int, i>;
namespace boost { namespace hana { namespace test {
template <>
auto instances<Maybe> = tuple(
type<Comparable>,
type<Orderable>,
type<Functor>,
type<Applicative>,
type<Monad>,
type<Traversable>,
type<Foldable>,
type<Searchable>
);
template <>
auto objects<Maybe> = tuple(
nothing,
just(ord<0>),
just(ord<1>),
just(ord<2>)
);
}}}
int main() {
test::check_datatype<Maybe>();
constexpr struct { } undefined{};
// Maybe methods
{
auto f = test::injection([]{});
auto x = test::injection([]{})();
auto y = test::injection([]{})();
// maybe
{
BOOST_HANA_CONSTANT_CHECK(equal(maybe(x, undefined, nothing), x));
BOOST_HANA_CONSTANT_CHECK(equal(maybe(undefined, f, just(x)), f(x)));
}
// is_nothing
{
BOOST_HANA_CONSTANT_CHECK(is_nothing(nothing));
BOOST_HANA_CONSTANT_CHECK(not_(is_nothing(just(undefined))));
}
// is_just
{
BOOST_HANA_CONSTANT_CHECK(is_just(just(undefined)));
BOOST_HANA_CONSTANT_CHECK(not_(is_just(nothing)));
}
// from_just
{
BOOST_HANA_CONSTANT_CHECK(equal(from_just(just(x)), x));
// from_just(nothing);
}
// from_maybe
{
BOOST_HANA_CONSTANT_CHECK(equal(from_maybe(x, nothing), x));
BOOST_HANA_CONSTANT_CHECK(equal(from_maybe(undefined, just(y)), y));
}
// only_when
{
BOOST_HANA_CONSTANT_CHECK(equal(
only_when(always(true_), f, x),
just(f(x))
));
BOOST_HANA_CONSTANT_CHECK(equal(
only_when(always(false_), f, x),
nothing
));
BOOST_HANA_CONSTANT_CHECK(equal(
only_when(always(false_), undefined, x),
nothing
));
}
}
// Comparable
{
// equal
{
auto x = test::injection([]{})();
auto y = test::injection([]{})();
BOOST_HANA_CONSTANT_CHECK(equal(nothing, nothing));
BOOST_HANA_CONSTANT_CHECK(not_(equal(nothing, just(x))));
BOOST_HANA_CONSTANT_CHECK(not_(equal(just(x), nothing)));
BOOST_HANA_CONSTANT_CHECK(equal(just(x), just(x)));
BOOST_HANA_CONSTANT_CHECK(not_(equal(just(x), just(y))));
}
}
// Orderable
{
// less
{
BOOST_HANA_CONSTANT_CHECK(less(nothing, just(undefined)));
BOOST_HANA_CONSTANT_CHECK(not_(less(just(undefined), nothing)));
BOOST_HANA_CONSTANT_CHECK(not_(less(nothing, nothing)));
BOOST_HANA_CONSTANT_CHECK(less(just(ord<0>), just(ord<1>)));
BOOST_HANA_CONSTANT_CHECK(not_(less(just(ord<0>), just(ord<0>))));
BOOST_HANA_CONSTANT_CHECK(not_(less(just(ord<1>), just(ord<0>))));
}
}
// Functor
{
// transform
{
auto f = test::injection([]{});
auto x = test::injection([]{})();
BOOST_HANA_CONSTANT_CHECK(equal(transform(nothing, f), nothing));
BOOST_HANA_CONSTANT_CHECK(equal(transform(just(x), f), just(f(x))));
}
}
// Applicative
{
auto f = test::injection([]{});
auto x = test::injection([]{})();
// ap
{
BOOST_HANA_CONSTANT_CHECK(equal(ap(nothing, nothing), nothing));
BOOST_HANA_CONSTANT_CHECK(equal(ap(just(f), nothing), nothing));
BOOST_HANA_CONSTANT_CHECK(equal(ap(nothing, just(x)), nothing));
BOOST_HANA_CONSTANT_CHECK(equal(ap(just(f), just(x)), just(f(x))));
}
// lift
{
BOOST_HANA_CONSTANT_CHECK(equal(lift<Maybe>(x), just(x)));
}
}
// Monad
{
// flatten
{
auto x = test::injection([]{})();
BOOST_HANA_CONSTANT_CHECK(equal(flatten(nothing), nothing));
BOOST_HANA_CONSTANT_CHECK(equal(flatten(just(nothing)), nothing));
BOOST_HANA_CONSTANT_CHECK(equal(flatten(just(just(x))), just(x)));
}
}
// Traversable
{
auto f = test::injection([]{});
auto x = test::injection([]{})();
auto applicative = test::identity;
using A = test::Identity;
// traverse
{
BOOST_HANA_CONSTANT_CHECK(equal(
traverse<A>(just(x), compose(applicative, f)),
applicative(just(f(x)))
));
BOOST_HANA_CONSTANT_CHECK(equal(
traverse<A>(nothing, compose(applicative, f)),
applicative(nothing)
));
}
}
// Searchable
{
auto x = test::injection([]{})();
auto y = test::injection([]{})();
auto is = [](auto x) {
return [=](auto y) { return equal(x, y); };
};
// find
{
BOOST_HANA_CONSTANT_CHECK(equal(
find(just(x), is(x)),
just(x)
));
BOOST_HANA_CONSTANT_CHECK(equal(
find(just(x), is(y)),
nothing
));
BOOST_HANA_CONSTANT_CHECK(equal(
find(nothing, is(x)),
nothing
));
// Previously, there was a bug that would make this fail.
auto non_const_nothing = nothing;
BOOST_HANA_CONSTANT_CHECK(equal(
find(non_const_nothing, is(x)),
nothing
));
}
// any
{
BOOST_HANA_CONSTANT_CHECK(any(just(x), is(x)));
BOOST_HANA_CONSTANT_CHECK(not_(any(just(x), is(y))));
BOOST_HANA_CONSTANT_CHECK(not_(any(nothing, is(x))));
}
}
// Foldable
{
auto x = test::injection([]{})();
auto s = test::injection([]{})();
auto f = test::injection([]{});
// foldl
{
BOOST_HANA_CONSTANT_CHECK(equal(foldl(just(x), s, f), f(s, x)));
BOOST_HANA_CONSTANT_CHECK(equal(foldl(nothing, s, f), s));
}
// foldr
{
BOOST_HANA_CONSTANT_CHECK(equal(foldr(just(x), s, f), f(x, s)));
BOOST_HANA_CONSTANT_CHECK(equal(foldr(nothing, s, f), s));
}
// unpack
{
BOOST_HANA_CONSTANT_CHECK(equal(unpack(nothing, f), f()));
BOOST_HANA_CONSTANT_CHECK(equal(unpack(just(x), f), f(x)));
// Previously, there was a bug that would make this fail.
auto non_const_nothing = nothing;
BOOST_HANA_CONSTANT_CHECK(equal(unpack(non_const_nothing, f), f()));
}
}
}