/*! @file Defines `boost::hana::experimental::types`. @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_EXPERIMENTAL_TYPES_HPP #define BOOST_HANA_EXPERIMENTAL_TYPES_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include BOOST_HANA_NAMESPACE_BEGIN namespace experimental { //! @ingroup group-experimental //! Container optimized for holding types. //! //! It is often useful to manipulate a sequence that contains types //! only, without any associated runtime value. This container allows //! storing and manipulating pure types in a much more compile-time //! efficient manner than using `hana::tuple`, which must assume that //! its contents might have runtime values. template struct types; struct types_tag; template struct types { }; } // end namespace experimental template struct tag_of> { using type = experimental::types_tag; }; // Foldable template <> struct unpack_impl { template ::value >::type> static constexpr decltype(auto) apply(hana::experimental::types const&, F&& f) { return static_cast(f)(hana::type{}...); } template ::value >::type> static constexpr hana::type::type> apply(hana::experimental::types const&, F const&) { return {}; } }; // Functor template <> struct transform_impl { template ::value >::type> static constexpr auto apply(hana::experimental::types const&, F&& f) -> hana::experimental::types{}))::type...> { return {}; } template ::value >::type> static constexpr hana::experimental::types::type...> apply(hana::experimental::types const&, F const&) { return {}; } }; // Iterable template <> struct at_impl { template static constexpr auto apply(hana::experimental::types const&, N const&) { using Nth = typename detail::type_at::type; return hana::type{}; } }; template <> struct is_empty_impl { template static constexpr hana::bool_ apply(hana::experimental::types const&) { return {}; } }; template <> struct drop_front_impl { template static hana::experimental::types::type...> helper(std::index_sequence); template static constexpr auto apply(hana::experimental::types const&, N const&) { constexpr std::size_t n = N::value > sizeof...(T) ? sizeof...(T) : N::value; using Indices = std::make_index_sequence; return decltype(helper(Indices{})){}; } }; // Searchable template <> struct contains_impl { template struct is_same_as { template struct apply { static constexpr bool value = std::is_same::value; }; }; template static constexpr auto apply(hana::experimental::types const&, U const&) -> hana::bool_< detail::any_of::template apply, T...>::value > { return {}; } static constexpr hana::false_ apply(...) { return {}; } }; // Comparable template <> struct equal_impl { template static constexpr hana::true_ apply(Types const&, Types const&) { return {}; } template static constexpr hana::false_ apply(Ts const&, Us const&) { return {}; } }; BOOST_HANA_NAMESPACE_END #endif // !BOOST_HANA_EXPERIMENTAL_TYPES_HPP