/*! @file Adapts `boost::mpl::list` for use with Hana. @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_EXT_BOOST_MPL_LIST_HPP #define BOOST_HANA_EXT_BOOST_MPL_LIST_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 #ifdef BOOST_HANA_DOXYGEN_INVOKED namespace boost { namespace mpl { //! @ingroup group-ext-mpl //! Adapter for Boost.MPL lists. //! //! //! Modeled concepts //! ---------------- //! It is possible for MPL lists to model a couple of concepts. //! However, because they are only able to hold types, they lack //! the generality required to model concepts like `Functor`, //! `Sequence` and other related concepts. //! //! 1. `Comparable`\n //! Two MPL lists are equal if and only if they contain the same //! number of types, and if all those types are equal. //! @include example/ext/boost/mpl/list/comparable.cpp //! //! 2. `Foldable`\n //! Folding a MPL list is equivalent to folding it as a `Sequence`. //! @include example/ext/boost/mpl/list/foldable.cpp //! //! 3. `Iterable`\n //! Iterating over a MPL list is just iterating over each of the //! types it contains, as if it were a `Sequence`. //! @include example/ext/boost/mpl/list/iterable.cpp //! //! 4. `Searchable`\n //! A MPL list can be searched as if it were a tuple containing //! `hana::type`s. //! @include example/ext/boost/mpl/list/searchable.cpp //! //! //! Conversion from any `Foldable` //! ------------------------------ //! A MPL list can be created from any `Foldable`. More precisely, //! for a `Foldable` `xs` whose linearization is `[x1, ..., xn]`, //! @code //! to(xs) == mpl::list{} //! @endcode //! where `tk` is the type of `xk`, or the type contained in `xk` if //! `xk` is a `hana::type`. //! @warning //! The limitations on the size of `mpl::list`s are inherited by //! this conversion utility, and hence trying to convert a `Foldable` //! containing more than [BOOST_MPL_LIMIT_LIST_SIZE][1] elements is //! an error. //! @include example/ext/boost/mpl/list/conversion.cpp //! //! [1]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/limit-list-size.html template struct list { }; }} #endif BOOST_HANA_NAMESPACE_BEGIN namespace ext { namespace boost { namespace mpl { using list_tag = ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type; }}} template struct tag_of::type, ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type >::value >> { using type = ext::boost::mpl::list_tag; }; ////////////////////////////////////////////////////////////////////////// // Comparable ////////////////////////////////////////////////////////////////////////// template <> struct equal_impl { template static constexpr auto apply(Xs const&, Ys const&) { return typename ::boost::mpl::equal::type{}; } }; ////////////////////////////////////////////////////////////////////////// // Foldable ////////////////////////////////////////////////////////////////////////// template <> struct length_impl { template static constexpr auto apply(Xs const&) { return hana::size_c< ::boost::mpl::size::type::value>; } }; ////////////////////////////////////////////////////////////////////////// // Iterable ////////////////////////////////////////////////////////////////////////// template <> struct at_impl { template static constexpr auto apply(Ts const&, N const&) { constexpr std::size_t n = N::value; using T = typename ::boost::mpl::at_c::type; return hana::type_c; } }; template <> struct drop_front_impl { template static constexpr auto drop_front_helper(Xs const&, std::index_sequence) { return boost::mpl::list< typename boost::mpl::at_c::type... >{}; } template static constexpr auto apply(Xs const& xs, N const&) { constexpr std::size_t n = N::value; constexpr std::size_t len = decltype(hana::length(xs))::value; return drop_front_helper(xs, std::make_index_sequence<(n < len ? len - n : 0)>{}); } }; template <> struct is_empty_impl { template static constexpr auto apply(Xs const&) { return typename ::boost::mpl::empty::type{}; } }; ////////////////////////////////////////////////////////////////////////// // Conversion from a Foldable ////////////////////////////////////////////////////////////////////////// template struct to_impl::value>> { template static constexpr decltype(auto) apply(Xs&& xs) { auto list_type = hana::unpack(static_cast(xs), hana::template_<::boost::mpl::list>); return typename decltype(list_type)::type{}; } }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_EXT_BOOST_MPL_LIST_HPP