Search code examples
c++boost-hana

Conversions Between STL and Hana tuples


#include <boost/hana.hpp>
#include <iostream>
#include <tuple>

namespace hana = boost::hana;

int main()
{
    int x{7};
    float y{3.14};
    double z{2.7183};
    auto t = hana::to<hana::tuple_tag>(std::tie(x, y, z));
    hana::for_each(t, [](auto& o) { std::cout << o << '\n'; });
}

What's the hana way of accomplishing this? I realize I can use: hana::make_tuple(std::ref(x), std::ref(y), std::ref(z)), but this seems unnecessarily verbose.


Solution

  • To convert between a hana::tuple and a std::tuple, you need to make std::tuple a valid Hana sequence. Since std::tuple is supported out-of-the-box, you just need to include <boost/hana/ext/std/tuple.hpp>. Hence, the following code works:

    #include <boost/hana.hpp>
    #include <boost/hana/ext/std/tuple.hpp>
    #include <iostream>
    #include <tuple>
    namespace hana = boost::hana;
    
    int main() {
        int x{7};
        float y{3.14};
        double z{2.7183};
        auto t = hana::to<hana::tuple_tag>(std::tie(x, y, z));
        hana::for_each(t, [](auto& o) { std::cout << o << '\n'; });
    }
    

    Note that you can also use hana::to_tuple for less verbosity:

    auto t = hana::to_tuple(std::tie(x, y, z));
    

    That being said, since you're using std::tie, you probably want to create a hana::tuple containing references, right? That is not possible right now, see this for the reason. However, you can simply use std::tuple in hana::for_each, provided you include the adapter header above:

    #include <boost/hana.hpp>
    #include <boost/hana/ext/std/tuple.hpp>
    #include <iostream>
    #include <tuple>
    namespace hana = boost::hana;
    
    int main() {
        int x{7};
        float y{3.14};
        double z{2.7183};
        auto t = std::tie(x, y, z);
        hana::for_each(t, [](auto& o) { std::cout << o << '\n'; });
    }