These are chat archives for boostorg/hana

26th
Sep 2017
Alastair Rankine
@randomphrase
Sep 26 2017 13:24
Hi I have a possibly newbie question, hope someone can help.
So I want to do type manipulation on a std::tuple. Let’s just say that the std::tuple is defined elsewhere and I don’t want to change it to a hana::tuple. However I do want to do type transformations/filters on this - and I don’t mind outputting a hana::tuple.
IIUC a std::tuple can be used as a hana-conformant sequence, with the #inclusion of the appropriate adaptor. However, I can’t see a way to ‘lift’ (?) the std::tuple so that it can do type manipulations.
For instance, if I want to use std::tuple<int, char> with hana::transform (for example with hana::add_pointer), I first need to convert the std::tuple to std::tuple<hana::type_c<int>, hana::type_c<char>> - is this correct? In which case I can’t see an obvious way to do this. Does such a facility exist in Hana and if so how do I use it? Thanks.
Alastair Rankine
@randomphrase
Sep 26 2017 13:51
Oops of course I need to convert std::tuple<int, char> to std::tuple<hana::type<int>, hana::type<char>>.
As it turns out I also need to convert the result (a hana::tuple<hana::type<int *>, hana::type<char *>> for example) into an MPL-conformant sequence of types such as hana::tuple<int *, char *>. Seems like a similar transformation and also seems like something that should exist in Hana already?
Maybe I’m overlooking something, FWIW I am using Hana 1.0.1 from boost 1.62.
Andreas Pokorny
@APokorny
Sep 26 2017 14:03
sounds like a one liner taking a std tuple <Args...> and returing a hana::tuple<type_c<Args>...>
Alastair Rankine
@randomphrase
Sep 26 2017 14:07
Sure. Something like:
template <typename ... Args>
constexpr auto to_hana_types(std::tuple<Args...>) { return hana::tuple<hana::type<Args> ...>{}; }
Seems like it should be part of hana though?
Alastair Rankine
@randomphrase
Sep 26 2017 14:27
Actually I think the above ‘one-liner’ is oversimplified. In the general case (eg reference types) it may not be easy to instantiate this type, in order to call the function in the first place. Hence I think this may need to be a pure type transformation, using (for example) a partially specialized template class and traditional metaprogramming. Perhaps this is why it is not part of hana?
Jason Rice
@ricejasonf
Sep 26 2017 16:15
You could do hana::transform(xs, hana::typeid_) which would yield a std::tuple<hana::type<T>...>
Jason Rice
@ricejasonf
Sep 26 2017 16:25
... and types can be passed in to a hana::Metafunction like this hana::unpack(my_types, hana::template_<hana::tuple>) which would return a hana::type<hana::tuple<T...>>
There is also hana::experimental::types which is a just a list of types represented like types<T...> instead of wrapping everything in type like hana::tuple<hana::type<T>...>
Alastair Rankine
@randomphrase
Sep 26 2017 17:07
@ricejasonf interesting, thanks! I’m assuming that I could also unpack into an MPL container like mpl::vector?
Alastair Rankine
@randomphrase
Sep 26 2017 17:21
Also can confirm your solution works for me - including unpacking into an MPL container, nice! However, I did try it with a reference type in the input std::tuple, and sure enough I could not instantiate it to pass into hana::transform. Not sure what the generic answer would be here.
Jason Rice
@ricejasonf
Sep 26 2017 17:33
Do you have a minimal code example? When dealing with types you typically want to keep it wrapped in hana::type so you don't instantiate it.
Jason Rice
@ricejasonf
Sep 26 2017 17:40
boostorg/hana#326
Alastair Rankine
@randomphrase
Sep 26 2017 17:41
The problem is with the first argument to hana::transform. I want to do type manipulations on a std::tuple (which as I described is generated upstream, and can’t easily be changed to a hana tuple). Currently I can call hana::transform(my_tuple{}, hana::typeid_) as you suggested above.
However this is predicated on my_tuple being default constructible, which is not necessarily the case for all tuples. Changing the default constructor to hana::type_c<my_tuple> does not work.
Jason Rice
@ricejasonf
Sep 26 2017 17:44
If you just want to convert all the types to references perhaps a simple mpl style metafunction would be the most efficient.
like template <typename ...T> struct to_refs<std::tuple<T...>> { using type = std::tuple<T&...>; };
That way you don't instantiate stuff for every T
... or consider the code snippet in the top of the issue 326
Alastair Rankine
@randomphrase
Sep 26 2017 18:03
Got it, sounds like #326 might be the more generic solution. Thanks for your help.