From 9b93fb0eb0c87732a2400087b7909228141da8b2 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Sun, 20 Sep 2015 09:22:15 -0700 Subject: [PATCH] Add experimental views Closes #193 --- include/boost/hana/experimental/view.hpp | 512 ++++++++++++++++++ test/experimental/view/empty/is_empty.cpp | 18 + test/experimental/view/empty/length.cpp | 23 + test/experimental/view/empty/unpack.cpp | 26 + test/experimental/view/joined/at.cpp | 99 ++++ test/experimental/view/joined/is_empty.cpp | 45 ++ test/experimental/view/joined/length.cpp | 91 ++++ test/experimental/view/joined/unpack.cpp | 83 +++ test/experimental/view/single/at.cpp | 26 + test/experimental/view/single/is_empty.cpp | 21 + test/experimental/view/single/length.cpp | 25 + test/experimental/view/single/unpack.cpp | 27 + test/experimental/view/sliced/at.cpp | 93 ++++ test/experimental/view/sliced/is_empty.cpp | 51 ++ test/experimental/view/sliced/length.cpp | 70 +++ test/experimental/view/sliced/unpack.cpp | 137 +++++ test/experimental/view/transformed/ap.cpp | 124 +++++ test/experimental/view/transformed/at.cpp | 75 +++ .../view/transformed/drop_front.cpp | 100 ++++ test/experimental/view/transformed/equal.cpp | 52 ++ .../view/transformed/is_empty.cpp | 38 ++ .../view/transformed/laziness.cpp | 22 + test/experimental/view/transformed/length.cpp | 51 ++ test/experimental/view/transformed/less.cpp | 60 ++ .../view/transformed/transform.cpp | 59 ++ test/experimental/view/transformed/unpack.cpp | 36 ++ 26 files changed, 1964 insertions(+) create mode 100644 include/boost/hana/experimental/view.hpp create mode 100644 test/experimental/view/empty/is_empty.cpp create mode 100644 test/experimental/view/empty/length.cpp create mode 100644 test/experimental/view/empty/unpack.cpp create mode 100644 test/experimental/view/joined/at.cpp create mode 100644 test/experimental/view/joined/is_empty.cpp create mode 100644 test/experimental/view/joined/length.cpp create mode 100644 test/experimental/view/joined/unpack.cpp create mode 100644 test/experimental/view/single/at.cpp create mode 100644 test/experimental/view/single/is_empty.cpp create mode 100644 test/experimental/view/single/length.cpp create mode 100644 test/experimental/view/single/unpack.cpp create mode 100644 test/experimental/view/sliced/at.cpp create mode 100644 test/experimental/view/sliced/is_empty.cpp create mode 100644 test/experimental/view/sliced/length.cpp create mode 100644 test/experimental/view/sliced/unpack.cpp create mode 100644 test/experimental/view/transformed/ap.cpp create mode 100644 test/experimental/view/transformed/at.cpp create mode 100644 test/experimental/view/transformed/drop_front.cpp create mode 100644 test/experimental/view/transformed/equal.cpp create mode 100644 test/experimental/view/transformed/is_empty.cpp create mode 100644 test/experimental/view/transformed/laziness.cpp create mode 100644 test/experimental/view/transformed/length.cpp create mode 100644 test/experimental/view/transformed/less.cpp create mode 100644 test/experimental/view/transformed/transform.cpp create mode 100644 test/experimental/view/transformed/unpack.cpp diff --git a/include/boost/hana/experimental/view.hpp b/include/boost/hana/experimental/view.hpp new file mode 100644 index 0000000000..e47674c25d --- /dev/null +++ b/include/boost/hana/experimental/view.hpp @@ -0,0 +1,512 @@ +/* +@file +Defines experimental views. + +@copyright Louis Dionne 2013-2016 +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_EXPERIMENTAL_VIEW_HPP +#define BOOST_HANA_EXPERIMENTAL_VIEW_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// Pros of views +// - No temporary container created between algorithms +// - Lazy, so only the minimum is required +// +// Cons of views +// - Reference semantics mean possibility for dangling references +// - Lose the ability to move from temporary containers +// - When fetching the members of a view multiple times, no caching is done. +// So for example, `t = transform(xs, f); at_c<0>(t); at_c<0>(t)` will +// compute `f(at_c<0>(xs))` twice. +// - push_back creates a joint_view and a single_view. The single_view holds +// the value as a member. When doing multiple push_backs, we end up with a +// joint_view, joint_view, ....>>> +// which contains a reference to `xxx` and all the `T`s by value. Such a +// "view" is not cheap to copy, which is inconsistent with the usual +// expectations about views. + +BOOST_HANA_NAMESPACE_BEGIN + +namespace experimental { + struct view_tag; + + namespace detail { + template + struct is_view { + static constexpr bool value = false; + }; + + template + using view_storage = typename std::conditional< + detail::is_view::value, Sequence, Sequence& + >::type; + } + + ////////////////////////////////////////////////////////////////////////// + // sliced_view + ////////////////////////////////////////////////////////////////////////// + template + struct sliced_view_t { + detail::view_storage sequence_; + using hana_tag = view_tag; + }; + + template + constexpr auto sliced(Sequence& sequence, Indices const& indices) { + return hana::unpack(indices, [&](auto ...i) { + return sliced_view_t{sequence}; + }); + } + + namespace detail { + template + struct is_view> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // transformed_view + ////////////////////////////////////////////////////////////////////////// + template + struct transformed_view_t { + detail::view_storage sequence_; + F f_; + using hana_tag = view_tag; + }; + + template + constexpr transformed_view_t::type> + transformed(Sequence& sequence, F&& f) { + return {sequence, static_cast(f)}; + } + + namespace detail { + template + struct is_view> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // filtered_view + ////////////////////////////////////////////////////////////////////////// +#if 0 + template + using filtered_view_t = sliced_view_t>; + + template + constexpr filtered_view_t filtered(Sequence& sequence, Pred&& pred) { + return {sequence}; + } +#endif + + ////////////////////////////////////////////////////////////////////////// + // joined_view + ////////////////////////////////////////////////////////////////////////// + template + struct joined_view_t { + detail::view_storage sequence1_; + detail::view_storage sequence2_; + using hana_tag = view_tag; + }; + + struct make_joined_view_t { + template + constexpr joined_view_t operator()(Sequence1& s1, Sequence2& s2) const { + return {s1, s2}; + } + }; + constexpr make_joined_view_t joined{}; + + namespace detail { + template + struct is_view> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // single_view + ////////////////////////////////////////////////////////////////////////// + template + struct single_view_t { + T value_; + using hana_tag = view_tag; + }; + + template + constexpr single_view_t::type> single_view(T&& t) { + return {static_cast(t)}; + } + + namespace detail { + template + struct is_view> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // empty_view + ////////////////////////////////////////////////////////////////////////// + struct empty_view_t { + using hana_tag = view_tag; + }; + + constexpr empty_view_t empty_view() { + return {}; + } + + namespace detail { + template <> + struct is_view { + static constexpr bool value = true; + }; + } +} // end namespace experimental + +////////////////////////////////////////////////////////////////////////// +// Foldable +////////////////////////////////////////////////////////////////////////// +template <> +struct unpack_impl { + // sliced_view + template + static constexpr decltype(auto) + apply(experimental::sliced_view_t view, F&& f) { + return static_cast(f)(hana::at_c(view.sequence_)...); + } + + // transformed_view + template + static constexpr decltype(auto) + apply(experimental::transformed_view_t view, G&& g) { + return hana::unpack(view.sequence_, hana::on(static_cast(g), view.f_)); + } + + // joined_view + template + static constexpr decltype(auto) + unpack_joined(View view, F&& f, std::index_sequence, + std::index_sequence) + { + return static_cast(f)(hana::at_c(view.sequence1_)..., + hana::at_c(view.sequence2_)...); + } + + template + static constexpr decltype(auto) + apply(experimental::joined_view_t view, F&& f) { + constexpr auto N1 = decltype(hana::length(view.sequence1_))::value; + constexpr auto N2 = decltype(hana::length(view.sequence2_))::value; + return unpack_joined(view, static_cast(f), + std::make_index_sequence{}, + std::make_index_sequence{}); + } + + // single_view + template + static constexpr decltype(auto) apply(experimental::single_view_t view, F&& f) { + return static_cast(f)(view.value_); + } + + // empty_view + template + static constexpr decltype(auto) apply(experimental::empty_view_t, F&& f) { + return static_cast(f)(); + } +}; + +////////////////////////////////////////////////////////////////////////// +// Iterable +////////////////////////////////////////////////////////////////////////// +template <> +struct at_impl { + // sliced_view + template + static constexpr decltype(auto) + apply(experimental::sliced_view_t view, N const&) { + constexpr std::size_t indices[] = {i...}; + constexpr std::size_t n = indices[N::value]; + return hana::at_c(view.sequence_); + } + + // transformed_view + template + static constexpr decltype(auto) + apply(experimental::transformed_view_t view, N const& n) { + return view.f_(hana::at(view.sequence_, n)); + } + + // joined_view + template + static constexpr decltype(auto) at_joined_view(View view, N const&, hana::true_) { + return hana::at_c(view.sequence1_); + } + + template + static constexpr decltype(auto) at_joined_view(View view, N const&, hana::false_) { + return hana::at_c(view.sequence2_); + } + + template + static constexpr decltype(auto) + apply(experimental::joined_view_t view, N const& n) { + constexpr auto Left = decltype(hana::length(view.sequence1_))::value; + return at_joined_view(view, n, hana::bool_c<(N::value < Left)>); + } + + // single_view + template + static constexpr decltype(auto) apply(experimental::single_view_t view, N const&) { + static_assert(N::value == 0, + "trying to fetch an out-of-bounds element in a hana::single_view"); + return view.value_; + } + + // empty_view + template + static constexpr decltype(auto) apply(experimental::empty_view_t, N const&) = delete; +}; + +template <> +struct length_impl { + // sliced_view + template + static constexpr auto + apply(experimental::sliced_view_t) { + return hana::size_c; + } + + // transformed_view + template + static constexpr auto apply(experimental::transformed_view_t view) { + return hana::length(view.sequence_); + } + + // joined_view + template + static constexpr auto apply(experimental::joined_view_t view) { + return hana::size_c< + decltype(hana::length(view.sequence1_))::value + + decltype(hana::length(view.sequence2_))::value + >; + } + + // single_view + template + static constexpr auto apply(experimental::single_view_t) { + return hana::size_c<1>; + } + + // empty_view + static constexpr auto apply(experimental::empty_view_t) { + return hana::size_c<0>; + } +}; + +template <> +struct is_empty_impl { + // sliced_view + template + static constexpr auto + apply(experimental::sliced_view_t) { + return hana::bool_c; + } + + // transformed_view + template + static constexpr auto apply(experimental::transformed_view_t view) { + return hana::is_empty(view.sequence_); + } + + // joined_view + template + static constexpr auto apply(experimental::joined_view_t view) { + return hana::and_(hana::is_empty(view.sequence1_), + hana::is_empty(view.sequence2_)); + } + + // single_view + template + static constexpr auto apply(experimental::single_view_t) { + return hana::false_c; + } + + // empty_view + static constexpr auto apply(experimental::empty_view_t) { + return hana::true_c; + } +}; + +template <> +struct drop_front_impl { + template + static constexpr auto apply(View view, N const&) { + constexpr auto n = N::value; + constexpr auto Length = decltype(hana::length(view))::value; + return experimental::sliced(view, hana::range_c); + } +}; + +////////////////////////////////////////////////////////////////////////// +// Functor +////////////////////////////////////////////////////////////////////////// +template <> +struct transform_impl { + template + static constexpr auto + apply(experimental::transformed_view_t view, G&& g) { + return experimental::transformed(view.sequence_, + hana::compose(static_cast(g), view.f_)); + } + + template + static constexpr auto apply(View view, F&& f) { + return experimental::transformed(view, static_cast(f)); + } +}; + +////////////////////////////////////////////////////////////////////////// +// Applicative +////////////////////////////////////////////////////////////////////////// +template <> +struct lift_impl { + template + static constexpr auto apply(T&& t) { + return experimental::single_view(static_cast(t)); + } +}; + +template <> +struct ap_impl { + template + static constexpr auto apply(F&& f, X&& x) { + // TODO: Implement cleverly; we most likely need a cartesian_product + // view or something like that. + return hana::ap(hana::to_tuple(f), hana::to_tuple(x)); + } +}; + +////////////////////////////////////////////////////////////////////////// +// Monad +////////////////////////////////////////////////////////////////////////// +template <> +struct flatten_impl { + template + static constexpr auto apply(View view) { + // TODO: Implement a flattened_view instead + return hana::fold_left(view, experimental::empty_view(), + experimental::joined); + } +}; + +////////////////////////////////////////////////////////////////////////// +// MonadPlus +////////////////////////////////////////////////////////////////////////// +template <> +struct concat_impl { + template + static constexpr auto apply(View1 view1, View2 view2) { + return experimental::joined(view1, view2); + } +}; + +template <> +struct empty_impl { + static constexpr auto apply() { + return experimental::empty_view(); + } +}; + +////////////////////////////////////////////////////////////////////////// +// Comparable +////////////////////////////////////////////////////////////////////////// +template <> +struct equal_impl { + template + static constexpr auto apply(View1 v1, View2 v2) { + // TODO: Use a lexicographical comparison algorithm. + return hana::equal(hana::to_tuple(v1), hana::to_tuple(v2)); + } +}; + +template +struct equal_impl::value>> { + template + static constexpr auto apply(View1 v1, Seq const& s) { + // TODO: Use a lexicographical comparison algorithm. + return hana::equal(hana::to_tuple(v1), hana::to_tuple(s)); + } +}; + +template +struct equal_impl::value>> { + template + static constexpr auto apply(Seq const& s, View2 v2) { + // TODO: Use a lexicographical comparison algorithm. + return hana::equal(hana::to_tuple(s), hana::to_tuple(v2)); + } +}; + +////////////////////////////////////////////////////////////////////////// +// Orderable +////////////////////////////////////////////////////////////////////////// +template <> +struct less_impl { + template + static constexpr auto apply(View1 v1, View2 v2) { + return hana::lexicographical_compare(v1, v2); + } +}; + +template +struct less_impl::value>> { + template + static constexpr auto apply(View1 v1, Seq const& s) { + return hana::lexicographical_compare(v1, s); + } +}; + +template +struct less_impl::value>> { + template + static constexpr auto apply(Seq const& s, View2 v2) { + return hana::lexicographical_compare(s, v2); + } +}; + +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXPERIMENTAL_VIEW_HPP diff --git a/test/experimental/view/empty/is_empty.cpp b/test/experimental/view/empty/is_empty.cpp new file mode 100644 index 0000000000..fb6fcef04d --- /dev/null +++ b/test/experimental/view/empty/is_empty.cpp @@ -0,0 +1,18 @@ +/* +@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 +#include +#include +namespace hana = boost::hana; + + +int main() { + { + auto empty = hana::experimental::empty_view(); + BOOST_HANA_CONSTANT_CHECK(hana::is_empty(empty)); + } +} diff --git a/test/experimental/view/empty/length.cpp b/test/experimental/view/empty/length.cpp new file mode 100644 index 0000000000..0e70dc4b69 --- /dev/null +++ b/test/experimental/view/empty/length.cpp @@ -0,0 +1,23 @@ +/* +@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 +#include +#include +#include +#include +namespace hana = boost::hana; + + +int main() { + { + auto empty = hana::experimental::empty_view(); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(empty), + hana::size_c<0> + )); + } +} diff --git a/test/experimental/view/empty/unpack.cpp b/test/experimental/view/empty/unpack.cpp new file mode 100644 index 0000000000..e02875daa0 --- /dev/null +++ b/test/experimental/view/empty/unpack.cpp @@ -0,0 +1,26 @@ +/* +@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 +#include +#include +#include + +#include +namespace hana = boost::hana; + + +int main() { + auto f = hana::test::_injection<0>{}; + + { + auto empty = hana::experimental::empty_view(); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(empty, f), + f() + )); + } +} diff --git a/test/experimental/view/joined/at.cpp b/test/experimental/view/joined/at.cpp new file mode 100644 index 0000000000..c6f8d18e5b --- /dev/null +++ b/test/experimental/view/joined/at.cpp @@ -0,0 +1,99 @@ +/* +@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 +#include +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + + { + auto storage1 = container(ct_eq<0>{}); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<0>), + ct_eq<0>{} + )); + }{ + auto storage1 = container(); + auto storage2 = container(ct_eq<0>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<0>), + ct_eq<0>{} + )); + } + + { + auto storage1 = container(ct_eq<0>{}, ct_eq<1>{}); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<1>), + ct_eq<1>{} + )); + }{ + auto storage1 = container(ct_eq<0>{}); + auto storage2 = container(ct_eq<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<1>), + ct_eq<1>{} + )); + }{ + auto storage1 = container(); + auto storage2 = container(ct_eq<0>{}, ct_eq<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<1>), + ct_eq<1>{} + )); + } + + { + auto storage1 = container(ct_eq<0>{}, ct_eq<1>{}); + auto storage2 = container(ct_eq<2>{}, ct_eq<3>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<1>), + ct_eq<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<2>), + ct_eq<2>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(joined, hana::size_c<3>), + ct_eq<3>{} + )); + } +} diff --git a/test/experimental/view/joined/is_empty.cpp b/test/experimental/view/joined/is_empty.cpp new file mode 100644 index 0000000000..d7f6bcc589 --- /dev/null +++ b/test/experimental/view/joined/is_empty.cpp @@ -0,0 +1,45 @@ +/* +@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 +#include +#include +#include + +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + auto container = hana::test::seq; + + { + auto storage1 = container(); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::is_empty(joined)); + } + { + auto storage1 = container(undefined<0>{}); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(joined))); + } + { + auto storage1 = container(undefined<0>{}); + auto storage2 = container(undefined<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(joined))); + } + { + auto storage1 = container(); + auto storage2 = container(undefined<0>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(joined))); + } +} diff --git a/test/experimental/view/joined/length.cpp b/test/experimental/view/joined/length.cpp new file mode 100644 index 0000000000..f35769b53a --- /dev/null +++ b/test/experimental/view/joined/length.cpp @@ -0,0 +1,91 @@ +/* +@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 +#include +#include +#include +#include + +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + auto container = hana::test::seq; + + { + auto storage1 = container(); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<0> + )); + } + + { + auto storage1 = container(undefined<0>{}); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<1> + )); + } + + { + auto storage1 = container(); + auto storage2 = container(undefined<0>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<1> + )); + } + + { + auto storage1 = container(undefined<0>{}); + auto storage2 = container(undefined<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<2> + )); + } + + { + auto storage1 = container(undefined<0>{}); + auto storage2 = container(undefined<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<2> + )); + } + + { + auto storage1 = container(undefined<0>{}, undefined<1>{}); + auto storage2 = container(undefined<2>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<3> + )); + } + + { + auto storage1 = container(undefined<0>{}, undefined<1>{}, undefined<2>{}); + auto storage2 = container(undefined<3>{}, undefined<4>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(joined), + hana::size_c<5> + )); + } +} diff --git a/test/experimental/view/joined/unpack.cpp b/test/experimental/view/joined/unpack.cpp new file mode 100644 index 0000000000..d6032a556b --- /dev/null +++ b/test/experimental/view/joined/unpack.cpp @@ -0,0 +1,83 @@ +/* +@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 +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<0>{}; + + { + auto storage1 = container(); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f() + )); + } + + { + auto storage1 = container(ct_eq<0>{}); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f(ct_eq<0>{}) + )); + }{ + auto storage1 = container(); + auto storage2 = container(ct_eq<0>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f(ct_eq<0>{}) + )); + }{ + auto storage1 = container(ct_eq<0>{}); + auto storage2 = container(ct_eq<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f(ct_eq<0>{}, ct_eq<1>{}) + )); + } + + { + auto storage1 = container(ct_eq<0>{}, ct_eq<1>{}); + auto storage2 = container(); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f(ct_eq<0>{}, ct_eq<1>{}) + )); + }{ + auto storage1 = container(); + auto storage2 = container(ct_eq<0>{}, ct_eq<1>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f(ct_eq<0>{}, ct_eq<1>{}) + )); + }{ + auto storage1 = container(ct_eq<0>{}, ct_eq<1>{}); + auto storage2 = container(ct_eq<2>{}, ct_eq<3>{}); + auto joined = hana::experimental::joined(storage1, storage2); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(joined, f), + f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}) + )); + } +} diff --git a/test/experimental/view/single/at.cpp b/test/experimental/view/single/at.cpp new file mode 100644 index 0000000000..eb616aa936 --- /dev/null +++ b/test/experimental/view/single/at.cpp @@ -0,0 +1,26 @@ +/* +@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 +#include +#include +#include +#include + +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + { + auto single = hana::experimental::single_view(ct_eq<0>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(single, hana::size_c<0>), + ct_eq<0>{} + )); + } +} diff --git a/test/experimental/view/single/is_empty.cpp b/test/experimental/view/single/is_empty.cpp new file mode 100644 index 0000000000..e4e05ea366 --- /dev/null +++ b/test/experimental/view/single/is_empty.cpp @@ -0,0 +1,21 @@ +/* +@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 +#include +#include +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + { + auto single = hana::experimental::single_view(undefined<0>{}); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(single))); + } +} diff --git a/test/experimental/view/single/length.cpp b/test/experimental/view/single/length.cpp new file mode 100644 index 0000000000..78be5b6ee6 --- /dev/null +++ b/test/experimental/view/single/length.cpp @@ -0,0 +1,25 @@ +/* +@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 +#include +#include +#include +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + { + auto single = hana::experimental::single_view(undefined<0>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(single), + hana::size_c<1> + )); + } +} diff --git a/test/experimental/view/single/unpack.cpp b/test/experimental/view/single/unpack.cpp new file mode 100644 index 0000000000..784e8eb6b1 --- /dev/null +++ b/test/experimental/view/single/unpack.cpp @@ -0,0 +1,27 @@ +/* +@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 +#include +#include +#include + +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto f = hana::test::_injection<0>{}; + + { + auto single = hana::experimental::single_view(ct_eq<0>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(single, f), + f(ct_eq<0>{}) + )); + } +} diff --git a/test/experimental/view/sliced/at.cpp b/test/experimental/view/sliced/at.cpp new file mode 100644 index 0000000000..58a6c4b045 --- /dev/null +++ b/test/experimental/view/sliced/at.cpp @@ -0,0 +1,93 @@ +/* +@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 +#include +#include +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + + { + auto storage = container(ct_eq<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<0>{} + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<0>{} + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<1>{} + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<1>), + ct_eq<1>{} + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<1>), + ct_eq<0>{} + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<0>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<1>), + ct_eq<0>{} + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<0>), + ct_eq<1>{} + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at(sliced, hana::size_c<1>), + ct_eq<3>{} + )); + } +} diff --git a/test/experimental/view/sliced/is_empty.cpp b/test/experimental/view/sliced/is_empty.cpp new file mode 100644 index 0000000000..8f65768fc8 --- /dev/null +++ b/test/experimental/view/sliced/is_empty.cpp @@ -0,0 +1,51 @@ +/* +@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 +#include +#include +#include +#include + +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + auto container = hana::test::seq; + + { + auto storage = container(); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::is_empty(sliced)); + }{ + auto storage = container(undefined<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::is_empty(sliced)); + }{ + auto storage = container(undefined<0>{}, undefined<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::is_empty(sliced)); + } + + { + auto storage = container(undefined<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(sliced))); + }{ + auto storage = container(undefined<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(sliced))); + } + + { + auto storage = container(undefined<0>{}, undefined<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(sliced))); + } +} diff --git a/test/experimental/view/sliced/length.cpp b/test/experimental/view/sliced/length.cpp new file mode 100644 index 0000000000..06ba8104f3 --- /dev/null +++ b/test/experimental/view/sliced/length.cpp @@ -0,0 +1,70 @@ +/* +@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 +#include +#include +#include +#include +#include + +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + auto container = hana::test::seq; + + { + auto storage = container(); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(sliced), + hana::size_c<0> + )); + } + + { + auto storage = container(undefined<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(sliced), + hana::size_c<1> + )); + }{ + auto storage = container(undefined<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(sliced), + hana::size_c<0> + )); + } + + { + auto storage = container(undefined<0>{}, undefined<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(sliced), + hana::size_c<1> + )); + }{ + auto storage = container(undefined<0>{}, undefined<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(sliced), + hana::size_c<2> + )); + }{ + auto storage = container(undefined<0>{}, undefined<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(sliced), + hana::size_c<2> + )); + } +} diff --git a/test/experimental/view/sliced/unpack.cpp b/test/experimental/view/sliced/unpack.cpp new file mode 100644 index 0000000000..bf8be0bd71 --- /dev/null +++ b/test/experimental/view/sliced/unpack.cpp @@ -0,0 +1,137 @@ +/* +@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 +#include +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<0>{}; + + { + auto storage = container(); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f() + )); + } + + { + auto storage = container(ct_eq<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f() + )); + }{ + auto storage = container(ct_eq<0>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<0>{}) + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f() + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<0>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<0>{}, ct_eq<1>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<1>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<1>{}, ct_eq<0>{}) + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f() + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<0>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<1>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<2>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<0>{}, ct_eq<2>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<1>{}, ct_eq<1>{}) + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}); + auto sliced = hana::experimental::sliced(storage, hana::tuple_c); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(sliced, f), + f(ct_eq<3>{}, ct_eq<1>{}, ct_eq<0>{}, ct_eq<2>{}, ct_eq<2>{}) + )); + } +} diff --git a/test/experimental/view/transformed/ap.cpp b/test/experimental/view/transformed/ap.cpp new file mode 100644 index 0000000000..96101ae62b --- /dev/null +++ b/test/experimental/view/transformed/ap.cpp @@ -0,0 +1,124 @@ +/* +@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 +#include +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::_injection; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<99>{}; + + { + auto storage = container(); + auto functions = container(); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container() + )); + }{ + auto storage = container(ct_eq<0>{}); + auto functions = container(); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container() + )); + }{ + auto storage = container(); + auto functions = container(ct_eq<0>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container() + )); + } + + { + auto storage = container(ct_eq<0>{}); + auto functions = container(_injection<0>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container(_injection<0>{}(f(ct_eq<0>{}))) + )); + }{ + auto storage = container(ct_eq<0>{}); + auto functions = container(_injection<0>{}, _injection<1>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container(_injection<0>{}(f(ct_eq<0>{})), + _injection<1>{}(f(ct_eq<0>{}))) + )); + }{ + auto storage = container(ct_eq<0>{}); + auto functions = container(_injection<0>{}, _injection<1>{}, _injection<2>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container(_injection<0>{}(f(ct_eq<0>{})), + _injection<1>{}(f(ct_eq<0>{})), + _injection<2>{}(f(ct_eq<0>{}))) + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto functions = container(_injection<0>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container(_injection<0>{}(f(ct_eq<0>{})), + _injection<0>{}(f(ct_eq<1>{}))) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto functions = container(_injection<0>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container(_injection<0>{}(f(ct_eq<0>{})), + _injection<0>{}(f(ct_eq<1>{})), + _injection<0>{}(f(ct_eq<2>{}))) + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto functions = container(_injection<0>{}, _injection<1>{}); + auto transformed_storage = hana::experimental::transformed(storage, f); + auto transformed_functions = hana::experimental::transformed(functions, hana::id); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::ap(transformed_functions, transformed_storage), + container(_injection<0>{}(f(ct_eq<0>{})), + _injection<0>{}(f(ct_eq<1>{})), + _injection<0>{}(f(ct_eq<2>{})), + + _injection<1>{}(f(ct_eq<0>{})), + _injection<1>{}(f(ct_eq<1>{})), + _injection<1>{}(f(ct_eq<2>{}))) + )); + } +} diff --git a/test/experimental/view/transformed/at.cpp b/test/experimental/view/transformed/at.cpp new file mode 100644 index 0000000000..1c1592012f --- /dev/null +++ b/test/experimental/view/transformed/at.cpp @@ -0,0 +1,75 @@ +/* +@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 +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<0>{}; + + { + auto storage = container(ct_eq<0>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<0>(transformed), + f(ct_eq<0>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<0>(transformed), + f(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<1>(transformed), + f(ct_eq<1>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<0>(transformed), + f(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<1>(transformed), + f(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<2>(transformed), + f(ct_eq<2>{}) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<0>(transformed), + f(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<1>(transformed), + f(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<2>(transformed), + f(ct_eq<2>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::at_c<3>(transformed), + f(ct_eq<3>{}) + )); + } +} diff --git a/test/experimental/view/transformed/drop_front.cpp b/test/experimental/view/transformed/drop_front.cpp new file mode 100644 index 0000000000..92d4c61aa0 --- /dev/null +++ b/test/experimental/view/transformed/drop_front.cpp @@ -0,0 +1,100 @@ +/* +@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 +#include +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<0>{}; + + { + auto storage = container(); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<0>), + container() + )); + } + + { + auto storage = container(ct_eq<0>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<0>), + container(f(ct_eq<0>{})) + )); + }{ + auto storage = container(ct_eq<0>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<1>), + container() + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<0>), + container(f(ct_eq<0>{}), f(ct_eq<1>{})) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<1>), + container(f(ct_eq<1>{})) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<2>), + container() + )); + } + + { + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<0>), + container(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<1>), + container(f(ct_eq<1>{}), f(ct_eq<2>{})) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<2>), + container(f(ct_eq<2>{})) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::drop_front(transformed, hana::size_c<3>), + container() + )); + } +} diff --git a/test/experimental/view/transformed/equal.cpp b/test/experimental/view/transformed/equal.cpp new file mode 100644 index 0000000000..5c5a20371b --- /dev/null +++ b/test/experimental/view/transformed/equal.cpp @@ -0,0 +1,52 @@ +/* +@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 +#include +#include +#include +#include + +#include +namespace hana = boost::hana; + + +int main() { + auto container = hana::test::seq; + + auto xs = container(0, '1', 2.2); + auto tr = hana::experimental::transformed(xs, hana::id); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + tr, + container() + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + tr, + container(0) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + tr, + container(0, '1') + ))); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + tr, + container(0, '1', 2.2) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + tr, + container(0, '1', 2.2, 345) + ))); + + BOOST_HANA_RUNTIME_CHECK(hana::not_(hana::equal( + tr, + container('0', '1', '2') + ))); +} diff --git a/test/experimental/view/transformed/is_empty.cpp b/test/experimental/view/transformed/is_empty.cpp new file mode 100644 index 0000000000..1367caf9bb --- /dev/null +++ b/test/experimental/view/transformed/is_empty.cpp @@ -0,0 +1,38 @@ +/* +@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 +#include +#include +#include + +#include +namespace hana = boost::hana; + + +struct undefined { }; + +int main() { + auto container = hana::test::seq; + + { + auto xs = container(); + auto tr = hana::experimental::transformed(xs, undefined{}); + BOOST_HANA_CONSTANT_CHECK(hana::is_empty(tr)); + } + + { + auto xs = container(undefined{}); + auto tr = hana::experimental::transformed(xs, undefined{}); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(tr))); + } + + { + auto xs = container(undefined{}, undefined{}); + auto tr = hana::experimental::transformed(xs, undefined{}); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(tr))); + } +} diff --git a/test/experimental/view/transformed/laziness.cpp b/test/experimental/view/transformed/laziness.cpp new file mode 100644 index 0000000000..4287d46c0a --- /dev/null +++ b/test/experimental/view/transformed/laziness.cpp @@ -0,0 +1,22 @@ +/* +@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 + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +struct undefined { }; + +int main() { + // Make sure we do not evaluate the function unless required + auto storage = hana::test::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, undefined{}); + (void)transformed; +} diff --git a/test/experimental/view/transformed/length.cpp b/test/experimental/view/transformed/length.cpp new file mode 100644 index 0000000000..c604d94905 --- /dev/null +++ b/test/experimental/view/transformed/length.cpp @@ -0,0 +1,51 @@ +/* +@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 +#include +#include +#include +#include + +#include +namespace hana = boost::hana; + + +template struct undefined { }; + +int main() { + auto container = hana::test::seq; + + { + auto storage = container(); + auto transformed = hana::experimental::transformed(storage, undefined<99>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(transformed), + hana::size_c<0> + )); + }{ + auto storage = container(undefined<0>{}); + auto transformed = hana::experimental::transformed(storage, undefined<99>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(transformed), + hana::size_c<1> + )); + }{ + auto storage = container(undefined<0>{}, undefined<1>{}); + auto transformed = hana::experimental::transformed(storage, undefined<99>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(transformed), + hana::size_c<2> + )); + }{ + auto storage = container(undefined<0>{}, undefined<1>{}, undefined<2>{}); + auto transformed = hana::experimental::transformed(storage, undefined<99>{}); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::length(transformed), + hana::size_c<3> + )); + } +} diff --git a/test/experimental/view/transformed/less.cpp b/test/experimental/view/transformed/less.cpp new file mode 100644 index 0000000000..8c18511548 --- /dev/null +++ b/test/experimental/view/transformed/less.cpp @@ -0,0 +1,60 @@ +/* +@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 +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_ord; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<0>{}; + + { + auto storage = container(); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + transformed, + container() + ))); + }{ + auto storage = container(ct_ord<0>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::less( + container(), + transformed + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + container(f(ct_ord<0>{})), + transformed + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::less( + transformed, + container() + ))); + }{ + auto storage = container(ct_ord<0>{}, ct_ord<1>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::less( + container(), + transformed + )); + BOOST_HANA_CONSTANT_CHECK(hana::less( + container(f(ct_ord<0>{})), + transformed + )); + BOOST_HANA_CONSTANT_CHECK(hana::less( + container(f(ct_ord<0>{}), f(ct_ord<0>{})), + transformed + )); + } +} diff --git a/test/experimental/view/transformed/transform.cpp b/test/experimental/view/transformed/transform.cpp new file mode 100644 index 0000000000..5c2aeda9a0 --- /dev/null +++ b/test/experimental/view/transformed/transform.cpp @@ -0,0 +1,59 @@ +/* +@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 +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto container = hana::test::seq; + auto f = hana::test::_injection<0>{}; + auto g = hana::test::_injection<1>{}; + + { + auto storage = container(); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(transformed, g), + container() + )); + }{ + auto storage = container(ct_eq<0>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(transformed, g), + container(g(f(ct_eq<0>{}))) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(transformed, g), + container(g(f(ct_eq<0>{})), g(f(ct_eq<1>{}))) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(transformed, g), + container(g(f(ct_eq<0>{})), g(f(ct_eq<1>{})), g(f(ct_eq<2>{}))) + )); + }{ + auto storage = container(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}); + auto transformed = hana::experimental::transformed(storage, f); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::transform(transformed, g), + container(g(f(ct_eq<0>{})), g(f(ct_eq<1>{})), g(f(ct_eq<2>{})), g(f(ct_eq<3>{}))) + )); + } +} diff --git a/test/experimental/view/transformed/unpack.cpp b/test/experimental/view/transformed/unpack.cpp new file mode 100644 index 0000000000..94ffa47e2d --- /dev/null +++ b/test/experimental/view/transformed/unpack.cpp @@ -0,0 +1,36 @@ +/* +@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 +#include +#include +#include + +#include +#include +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto f = hana::test::_injection<0>{}; + auto g = hana::test::_injection<1>{}; + auto check = [=](auto ...x) { + auto storage = hana::test::seq(x...); + auto transformed = hana::experimental::transformed(storage, f); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(transformed, g), + g(f(x)...) + )); + }; + + check(); + check(ct_eq<0>{}); + check(ct_eq<0>{}, ct_eq<1>{}); + check(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}); + check(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}); +}