#include <iostream>
using namespace std;

template<typename ...>
struct void_type
{
    using type = void;
};

template<typename ...T>
using void_t = typename void_type<T...>::type;

#define HAS_TYPE(NAME) \
template<typename, typename = void> \
struct has_type_##NAME: std::false_type \
{}; \
template<typename T> \
struct has_type_##NAME<T, void_t<typename T::NAME>>: std::true_type \
{}

HAS_TYPE(MyType);

template<typename T, bool = has_type_MyType<T>::value>
struct MyTypeOrTupple_impl;

template<typename T>
struct MyTypeOrTupple_impl<T, true>
{ using type = typename T::MyType; };

template<typename T>
struct MyTypeOrTupple_impl<T, false>
{ using type = std::tuple<>; };

template<typename T> using MyTypeOrTupple = typename MyTypeOrTupple_impl<T>::type;

struct A
{
    using MyType = int;
};

struct B {};

int main()
{
    static_assert(std::is_same<MyTypeOrTupple<A>, A::MyType>{}, "!");
    static_assert(std::is_same<MyTypeOrTupple<B>, std::tuple<>>{}, "!");
}


