123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- // 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_FUNCTOR_HPP
- #define BOOST_HANA_TEST_LAWS_FUNCTOR_HPP
- #include <boost/hana/adjust.hpp>
- #include <boost/hana/adjust_if.hpp>
- #include <boost/hana/assert.hpp>
- #include <boost/hana/bool.hpp>
- #include <boost/hana/concept/comparable.hpp>
- #include <boost/hana/concept/functor.hpp>
- #include <boost/hana/concept/sequence.hpp>
- #include <boost/hana/core/make.hpp>
- #include <boost/hana/core/when.hpp>
- #include <boost/hana/equal.hpp>
- #include <boost/hana/eval_if.hpp>
- #include <boost/hana/fill.hpp>
- #include <boost/hana/for_each.hpp>
- #include <boost/hana/functional/always.hpp>
- #include <boost/hana/functional/capture.hpp>
- #include <boost/hana/functional/compose.hpp>
- #include <boost/hana/lazy.hpp>
- #include <boost/hana/replace.hpp>
- #include <boost/hana/replace_if.hpp>
- #include <boost/hana/transform.hpp>
- #include <laws/base.hpp>
- namespace boost { namespace hana { namespace test {
- template <typename F, typename = when<true>>
- struct TestFunctor : TestFunctor<F, laws> {
- using TestFunctor<F, laws>::TestFunctor;
- };
- template <typename F>
- struct TestFunctor<F, laws> {
- template <typename Xs, typename Elements>
- TestFunctor(Xs xs, Elements elements) {
- hana::for_each(xs, hana::capture(elements)([](auto elements, auto x) {
- static_assert(Functor<decltype(x)>{}, "");
- test::_injection<0> f{};
- test::_injection<1> g{};
- // identity
- BOOST_HANA_CHECK(hana::equal(
- hana::transform(x, id),
- x
- ));
- // composition
- BOOST_HANA_CHECK(hana::equal(
- hana::transform(x, hana::compose(f, g)),
- hana::transform(hana::transform(x, g), f)
- ));
- // method definitions in terms of transform/adjust_if
- hana::for_each(elements, hana::capture(x, f, elements)(
- [](auto x, auto f, auto elements, auto value) {
- BOOST_HANA_CHECK(hana::equal(
- hana::adjust(x, value, f),
- hana::adjust_if(x, hana::equal.to(value), f)
- ));
- hana::for_each(elements, hana::capture(x, value)(
- [](auto x, auto oldval, auto newval) {
- BOOST_HANA_CHECK(hana::equal(
- hana::replace(x, oldval, newval),
- hana::replace_if(x, hana::equal.to(oldval), newval)
- ));
- }));
- }));
- auto pred = hana::always(true_c);
- BOOST_HANA_CHECK(hana::equal(
- hana::adjust_if(x, pred, f),
- hana::transform(x, [=](auto z) {
- return hana::eval_if(pred(z),
- hana::make_lazy(f)(z),
- hana::make_lazy(z)
- );
- })
- ));
- test::_constant<0> v{};
- BOOST_HANA_CHECK(hana::equal(
- hana::replace_if(x, pred, v),
- hana::adjust_if(x, pred, hana::always(v))
- ));
- BOOST_HANA_CHECK(hana::equal(
- hana::fill(x, v),
- hana::replace_if(x, hana::always(true_c), v)
- ));
- }));
- }
- };
- template <typename S>
- struct TestFunctor<S, when<Sequence<S>::value>>
- : TestFunctor<S, laws>
- {
- struct undefined { };
- template <typename Xs, typename Elements>
- TestFunctor(Xs xs, Elements elements)
- : TestFunctor<S, laws>{xs, elements}
- {
- using test::ct_eq;
- using test::cx_eq;
- constexpr auto list = make<S>;
- //////////////////////////////////////////////////////////////////
- // replace_if
- //////////////////////////////////////////////////////////////////
- {
- auto a = ct_eq<888>{};
- auto b = ct_eq<999>{};
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(), undefined{}, undefined{}),
- list()
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(ct_eq<0>{}), equal.to(a), undefined{}),
- list(ct_eq<0>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(a), equal.to(a), b),
- list(b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}), equal.to(a), undefined{}),
- list(ct_eq<0>{}, ct_eq<1>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(a, ct_eq<1>{}), equal.to(a), b),
- list(b, ct_eq<1>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(ct_eq<0>{}, a), equal.to(a), b),
- list(ct_eq<0>{}, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(a, a), equal.to(a), b),
- list(b, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), equal.to(a), undefined{}),
- list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(a, ct_eq<1>{}, ct_eq<2>{}), equal.to(a), b),
- list(b, ct_eq<1>{}, ct_eq<2>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(ct_eq<0>{}, a, ct_eq<2>{}), equal.to(a), b),
- list(ct_eq<0>{}, b, ct_eq<2>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(ct_eq<0>{}, ct_eq<1>{}, a), equal.to(a), b),
- list(ct_eq<0>{}, ct_eq<1>{}, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(a, ct_eq<1>{}, a), equal.to(a), b),
- list(b, ct_eq<1>{}, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace_if(list(a, ct_eq<1>{}, a, ct_eq<3>{}, a), equal.to(a), b),
- list(b, ct_eq<1>{}, b, ct_eq<3>{}, b)
- ));
- }
- //////////////////////////////////////////////////////////////////
- // replace
- //////////////////////////////////////////////////////////////////
- {
- auto a = ct_eq<888>{};
- auto b = ct_eq<999>{};
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(), undefined{}, undefined{}),
- list()
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(ct_eq<0>{}), a, undefined{}),
- list(ct_eq<0>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(a), a, b),
- list(b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(ct_eq<0>{}, ct_eq<1>{}), a, undefined{}),
- list(ct_eq<0>{}, ct_eq<1>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(a, ct_eq<1>{}), a, b),
- list(b, ct_eq<1>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(ct_eq<0>{}, a), a, b),
- list(ct_eq<0>{}, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(a, a), a, b),
- list(b, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), a, undefined{}),
- list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(a, ct_eq<1>{}, ct_eq<2>{}), a, b),
- list(b, ct_eq<1>{}, ct_eq<2>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(ct_eq<0>{}, a, ct_eq<2>{}), a, b),
- list(ct_eq<0>{}, b, ct_eq<2>{})
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(ct_eq<0>{}, ct_eq<1>{}, a), a, b),
- list(ct_eq<0>{}, ct_eq<1>{}, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(a, ct_eq<1>{}, a), a, b),
- list(b, ct_eq<1>{}, b)
- ));
- BOOST_HANA_CONSTANT_CHECK(hana::equal(
- hana::replace(list(a, ct_eq<1>{}, a, ct_eq<3>{}, a), a, b),
- list(b, ct_eq<1>{}, b, ct_eq<3>{}, b)
- ));
- }
- }
- };
- }}} // end namespace boost::hana::test
- #endif // !BOOST_HANA_TEST_LAWS_FUNCTOR_HPP
|