// 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 TEST_SUPPORT_SEQ_HPP #define TEST_SUPPORT_SEQ_HPP #include #include #include #include #include #include #include #include #include struct Seq; template struct seq_type { explicit constexpr seq_type(Storage s) : storage(s) { } Storage storage; using hana_tag = Seq; }; struct seq_t { template constexpr auto operator()(Xs&& ...xs) const { auto storage = boost::hana::make_tuple(xs...); return seq_type(storage); } }; constexpr seq_t seq{}; namespace boost { namespace hana { ////////////////////////////////////////////////////////////////////////// // Foldable // // Define either one to select which MCD is used: // BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD // BOOST_HANA_TEST_FOLDABLE_UNPACK_MCD // BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD // // If neither is defined, the MCD used is unspecified. ////////////////////////////////////////////////////////////////////////// #ifdef BOOST_HANA_TEST_FOLDABLE_FOLD_LEFT_MCD template <> struct fold_left_impl { template static constexpr auto apply(Xs xs, S s, F f) { return hana::fold_left(xs.storage, s, f); } template static constexpr auto apply(Xs xs, F f) { return hana::fold_left(xs.storage, f); } }; #elif defined(BOOST_HANA_TEST_FOLDABLE_ITERABLE_MCD) template <> struct length_impl { template static constexpr auto apply(Xs const& xs) { return hana::length(xs.storage); } }; #else template <> struct unpack_impl { template static constexpr auto apply(Xs xs, F f) { return hana::unpack(xs.storage, f); } }; #endif ////////////////////////////////////////////////////////////////////////// // Iterable ////////////////////////////////////////////////////////////////////////// template <> struct at_impl { template static constexpr decltype(auto) apply(Xs&& xs, N&& n) { return hana::at(static_cast(xs).storage, n); } }; template <> struct drop_front_impl { template static constexpr auto apply(Xs xs, N n) { return hana::unpack(hana::drop_front(xs.storage, n), ::seq); } }; template <> struct is_empty_impl { template static constexpr auto apply(Xs xs) { return hana::is_empty(xs.storage); } }; ////////////////////////////////////////////////////////////////////////// // Sequence ////////////////////////////////////////////////////////////////////////// template <> struct Sequence { static constexpr bool value = true; }; template <> struct make_impl { template static constexpr auto apply(Xs&& ...xs) { return ::seq(static_cast(xs)...); } }; }} // end namespace boost::hana #endif // !TEST_SUPPORT_SEQ_HPP