Going from hana::tuple_t to hana::tuple
Asked Answered
A

2

5

I have a hana::tuple_t<int, char, double, float>, and I want to use this to create a hana::tuple<int, char, double, float>.

I thought that using hana::to<hana::tuple_tag> would transform the hana::tuple_t<int, char, double, float> into a hana::tuple<int, char, double, float>; but that is not the case since the following always fails:

auto oType = hana::tuple_t<int, char, double, float>;

BOOST_HANA_CONSTANT_ASSERT(
    hana::to<hana::tuple_tag>(oType)
    ==
    hana::make_tuple(1, 'C', 1.0, 1.0f)
);

I've also tried using hana::transform, but with no luck (although I suspect I'm doing it wrong):

auto vecs = hana::transform(typeList, [](auto t) {
    return typename decltype(t)::type{};
});

So, how do I go about turning a hana::tuple_t into a hana::tuple?

Anorak answered 10/1, 2017 at 17:2 Comment(2)
Default initialization will yield a value of 0, not 1 (or 1.0, or 'C'). Have you tried comparing it to the tuple hana::make_tuple(0, '\0', 0.0, 0.0f)?Peppermint
Yeah, I've tried that. The compiler errors up with :Severity static_assert failed "hana::to<hana::tuple_tag>(oType) == hana::make_tuple(0, 0.0, 0.0f)"Anorak
G
4

I believe what you really want here is something like

#include <boost/hana.hpp>
namespace hana = boost::hana;

constexpr auto types = hana::tuple_t<int, char, double, float>;
using Tuple = decltype(hana::unpack(types, hana::template_<hana::tuple>))::type;
// Tuple is hana::tuple<int, char, double, float>
// Now you can create such a tuple as you wish:
Tuple ts{1, 'x', 2.2, 3.4f};

Things like hana::template_ and hana::metafunction were built precisely to make this interoperation with types easy.

Gimmal answered 11/1, 2017 at 6:57 Comment(1)
You mentioned hana::metafunction and interoperation with types, so I assume that's what you'd use to go in the opposite direction (from the type hana::tuple<A,B,C> to the value hana::type_t<A,B,C>). Can you elaborate on how you actually do that?Hemolysis
S
4

hana::tuple_t is just a template variable that is itself already a hana::tuple so converting to hana::tuple won't change anything.

template <typename ...T>
constexpr hana::tuple<hana::type<T>...> tuple_t{};

As mentioned in the comments, your call to hana::transform default initializes each member so you would expect values such as 0 for integral types.

Also, you are using BOOST_HANA_CONSTANT_ASSERT which checks compile-time values only. Raw int, char, double, and float values will not be constexpr.

BOOST_HANA_RUNTIME_ASSERT works for run-time values:

#include <boost/hana.hpp>

namespace hana = boost::hana;

constexpr auto types = hana::tuple_t<int, char, double, float>;

struct init_from_type_fn
{
  template <typename Type>
  constexpr auto operator()(Type) const
  {
    return typename Type::type{};
  }
};

constexpr init_from_type_fn init_from_type{};

int main()
{
  BOOST_HANA_RUNTIME_ASSERT(
    hana::equal(
      hana::transform(types, init_from_type),
      hana::make_tuple(0, '\0', 0.0, 0.0f)
    )
  );
}
Swimmingly answered 10/1, 2017 at 17:48 Comment(4)
Looks like the problem is MSVC w/ Clang. It just doesn't like this code, but it runs fine on my vm using Clang.Anorak
What is the error? Maybe it isn't specifyng c++14? I don't use MSVC but I've heard of people using Hana with it.Swimmingly
It's a clang frontend command failed due to signal use. From what I gathered, the compiler is getting confused when it tries to put everything together. There's no way to throw a -v afaik, so I've considered it a brick wall.Anorak
Hana's wiki has some stuff about it. Hope it helps... github.com/boostorg/hana/wiki/Setting-up-Clang-on-WindowsSwimmingly
G
4

I believe what you really want here is something like

#include <boost/hana.hpp>
namespace hana = boost::hana;

constexpr auto types = hana::tuple_t<int, char, double, float>;
using Tuple = decltype(hana::unpack(types, hana::template_<hana::tuple>))::type;
// Tuple is hana::tuple<int, char, double, float>
// Now you can create such a tuple as you wish:
Tuple ts{1, 'x', 2.2, 3.4f};

Things like hana::template_ and hana::metafunction were built precisely to make this interoperation with types easy.

Gimmal answered 11/1, 2017 at 6:57 Comment(1)
You mentioned hana::metafunction and interoperation with types, so I assume that's what you'd use to go in the opposite direction (from the type hana::tuple<A,B,C> to the value hana::type_t<A,B,C>). Can you elaborate on how you actually do that?Hemolysis

© 2022 - 2024 — McMap. All rights reserved.