Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find out if a tuple contains a type?

Tags:

c++

c++11

Suppose I want to create a compile-time heterogenous container of unique types from some sequence of non-unique types. In order to do this I need to iterate over the source type (some kind of tuple) and check whether each type already exists in my "unique" tuple.

My question is: How can I check whether a tuple (or a boost::fusion container) contains a type?

I'm open to using either the STL or boost.

like image 263
quant Avatar asked Sep 21 '14 10:09

quant


People also ask

How do you check if a tuple contains a value?

Method 1: By using a loop: We will iterate through each items of the tuple one by one and compare it with the given value. If any value in the tuple is equal to the given value, it will return True. Else, it will return False.

How do you check that tuple A contains all elements of tuple B?

You can use set. issubset or set. issuperset to check if every element in one tuple or list is in other. Show activity on this post.


2 Answers

#include <tuple> #include <type_traits>  template <typename T, typename Tuple> struct has_type;  template <typename T> struct has_type<T, std::tuple<>> : std::false_type {};  template <typename T, typename U, typename... Ts> struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};  template <typename T, typename... Ts> struct has_type<T, std::tuple<T, Ts...>> : std::true_type {}; 

DEMO

And an additional alias, if the trait itself should be std::true_type or std::false_type :

template <typename T, typename Tuple> using tuple_contains_type = typename has_type<T, Tuple>::type; 
like image 197
Piotr Skotnicki Avatar answered Oct 16 '22 11:10

Piotr Skotnicki


In C++17 you can do it like this:

template <typename T, typename Tuple> struct has_type;  template <typename T, typename... Us> struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {}; 

In C++11 you have to roll your own or / disjunction. Here's a full C++11 version, with tests:

#include <tuple> #include <type_traits>  template<typename... Conds> struct or_ : std::false_type {};  template<typename Cond, typename... Conds> struct or_<Cond, Conds...> : std::conditional<Cond::value, std::true_type, or_<Conds...>>::type {};  /* // C++17 version: template<class... B> using or_ = std::disjunction<B...>; */    template <typename T, typename Tuple> struct has_type;  template <typename T, typename... Us> struct has_type<T, std::tuple<Us...>> : or_<std::is_same<T, Us>...> {};  // Tests static_assert(has_type<int, std::tuple<>>::value == false, "test"); static_assert(has_type<int, std::tuple<int>>::value == true, "test"); static_assert(has_type<int, std::tuple<float>>::value == false, "test"); static_assert(has_type<int, std::tuple<float, int>>::value == true, "test"); static_assert(has_type<int, std::tuple<int, float>>::value == true, "test"); static_assert(has_type<int, std::tuple<char, float, int>>::value == true, "test"); static_assert(has_type<int, std::tuple<char, float, bool>>::value == false, "test"); static_assert(has_type<const int, std::tuple<int>>::value == false, "test"); // we're using is_same so cv matters static_assert(has_type<int, std::tuple<const int>>::value == false, "test"); // we're using is_same so cv matters 
like image 44
Ross Bencina Avatar answered Oct 16 '22 10:10

Ross Bencina