If I have a variant, like so:
using my_variant = boost::variant<int, bool, std::string>;
Is there an easy way to extract the types the variant can contain into a Boost.Hana tuple so that the following holds:
using boost::hana::type;
static_assert(std::is_same<my_tuple, boost::hana::tuple<type<int>, type<bool>, type<std::string>>>{});
The following will work on develop
(since e13d826):
#include <boost/hana.hpp>
#include <boost/hana/ext/boost/mpl.hpp>
#include <boost/variant.hpp>
#include <string>
namespace hana = boost::hana;
using my_variant = boost::variant<int, bool, std::string>;
constexpr auto my_tuple = hana::to<hana::tuple_tag>(my_variant::types{});
// Note:
// In general, don't use std::is_same to compare hana::tuple; use == in
// because it will also work if the tuple contains hana::basic_types.
static_assert(my_tuple == hana::tuple_t<int, bool, std::string>, "");
What e13d826 did was add support for mpl::list
; only mpl::vector
was supported before, and boost::variant<>::types
is a mpl::list
. This is why my answer took a while to come; I was implementing that :-).
Edit
I did not explain why I'm using constexpr auto my_tuple = ...
instead of using my_tuple = decltype(...)
. Well, the reason is simply because knowing the type of my_tuple
is not really useful, since you can't rely on it. Indeed, if you look at the documentation of hana::type
, it's written that you can't rely on hana::type<T>
being anything specific. There are good reasons for this, but from a usability point of view it means that you can't rely on the type of hana::tuple<hana::type<...>, ...>
being anything specific either. When doing type-level computations, prefer value-level encoding (thus auto my_tuple = ...
) to type-level encoding. This is the specificity of Hana over MPL & friends, and you should try to stick with it as much as possible, or you'll find Hana to be really clunky (because not written with that in mind).