Check if tuple types are subsets of each other
Asked Answered
H

1

6

Say I have 2 tuples that are not instantiated. Is there an idiomatic way to check if one set is the subset of the other?

If this requires another type instead of hana::tuple_c, this is fine as well. Actually, my current input consists of std::tuple, but I couldn't get it working either way.

Code that does NOT work (but I feel like there should be something similar possible):

#include <boost/hana.hpp>
using namespace boost;

using SetA = hana::tuple_c<int, char, float>;
using SetB = hana::tuple_c<int, float>;

static_assert(
    hana::is_subset( SetB, SetA ),
    ""
);

My current workaround uses boost::mpl to do an intersection and then compare the results. This works, but I'm interested in a pure boost::hana solution:

#include <boost/mpl.hpp>
using namespace boost;

using SetA = mpl::set<int, char, float>;
using SetB = mpl::set<int, float>;

using Intersection = typename mpl::copy_if<
    SetA,
    mpl::has_key< SetB, mpl::_1 >,
    mpl::back_inserter< mpl::vector<> >
>::type;

// since Intersection is a vector, subset also needs vector type
using Subset = typename mpl::copy<
    SetB,
    mpl::back_inserter< mpl::vector<> >
>::type;

static_assert(std::is_same<Intersection, Subset>::value, "");
Hinge answered 7/1, 2016 at 10:12 Comment(0)
E
10

You're not using boost::hana correctly. This will work:

#include <boost/hana.hpp>
using namespace boost;

constexpr auto setA = hana::tuple_t<int, char, float>;
constexpr auto setB = hana::tuple_t<int, float>;

// Is `setB` a subset of `setA`? (Yes.)
static_assert(hana::is_subset(setB, setA), "");

// Is `setA` a subset of `setB`? (No.)
static_assert(!hana::is_subset(setA, setB), "");

Explanation:

hana::tuple_t<xs...> is shorthand notation for a tuple of hana::type_c objects.

  • auto x = hana::tuple_t<int, char>;
    // ...is equivalent to...
    auto x = hana::make_tuple(hana::type_c<int>, hana::type_c<char>);
    

hana::type_c objects wrap types into values.

hana::is_subset(a, b) checks if a is a subset of b, and not viceversa (you were checking if b was a subset of a in your question).

Espionage answered 7/1, 2016 at 10:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.