#include <utility>
#include <type_traits>
template<template<typename>class Test>
struct helper1 {
static std::integral_constant<int, 0> test(...);
template<typename T>
static std::integral_constant<int, 1> test(Test<T> const&);
};
template<template<typename>class Test>
struct helper2 {
static std::integral_constant<int, 5> test(...);
template<typename T, typename=typename std::enable_if<Test<T>::value>::type>
static std::integral_constant<int, 4> test(T const&);
};
template<template<typename>class Test, typename T, typename=void>
struct base_match :std::integral_constant<int, 2> {};
template<template<typename>class Test, typename T>
struct base_match<Test,T,
typename std::enable_if<0==decltype(helper1<Test>::test(std::declval<T const&>()))::value>::type>
:std::integral_constant<int, 3> {};
template<template<typename>class Test, typename T, typename=void>
struct base_match2 :std::integral_constant<int, 6> {};
template<template<typename>class Test, typename T>
struct base_match2<Test,T,
typename std::enable_if<0==decltype(helper2<Test>::test(std::declval<T const&>()))::value>::type>
:std::integral_constant<int, 7> {};
template<typename T> struct Foo {};
template<typename T> struct IsFoo: std::false_type {};
template<typename T> struct IsFoo<Foo<T>>: std::true_type {};
typedef Foo<double> Test0;
struct Test1: Foo<int> {};
struct Test2: Foo<int>, Foo<double> {};
struct Test3 {};
template<typename T>
using any_base_foo = base_match< Foo, T >;
template<typename T>
using any_base2_foo = base_match2< IsFoo, T >;
#include <iostream>
int main() {
std::cout << "true == " << any_base_foo<Test0>::value << "\n";
std::cout << "true == " << any_base_foo<Test1>::value << "\n";
std::cout << "true == " << any_base_foo<Test2>::value << "\n";
std::cout << "false == " << any_base_foo<Test3>::value << "\n";
std::cout << "false == " << any_base_foo<int>::value << "\n";
std::cout << "method 2\n";
std::cout << "true == " << any_base2_foo<Test0>::value << "\n";
std::cout << "true == " << any_base2_foo<Test1>::value << "\n";
std::cout << "true == " << any_base2_foo<Test2>::value << "\n";
std::cout << "false == " << any_base2_foo<Test3>::value << "\n";
std::cout << "false == " << any_base2_foo<int>::value << "\n";
}