summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/test/_include/laws/functor.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/test/_include/laws/functor.hpp')
-rw-r--r--src/boost/libs/hana/test/_include/laws/functor.hpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/_include/laws/functor.hpp b/src/boost/libs/hana/test/_include/laws/functor.hpp
new file mode 100644
index 000000000..d1ddbb4de
--- /dev/null
+++ b/src/boost/libs/hana/test/_include/laws/functor.hpp
@@ -0,0 +1,250 @@
+// 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