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 th
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