fork download
  1. #include <utility>
  2. #include <type_traits>
  3.  
  4. template<template<typename>class Test>
  5. struct helper1 {
  6. static std::integral_constant<int, 0> test(...);
  7. template<typename T>
  8. static std::integral_constant<int, 1> test(Test<T> const&);
  9. };
  10. template<template<typename>class Test>
  11. struct helper2 {
  12. static std::integral_constant<int, 5> test(...);
  13. template<typename T, typename=typename std::enable_if<Test<T>::value>::type>
  14. static std::integral_constant<int, 4> test(T const&);
  15. };
  16.  
  17. template<template<typename>class Test, typename T, typename=void>
  18. struct base_match :std::integral_constant<int, 2> {};
  19. template<template<typename>class Test, typename T>
  20. struct base_match<Test,T,
  21. typename std::enable_if<0==decltype(helper1<Test>::test(std::declval<T const&>()))::value>::type>
  22. :std::integral_constant<int, 3> {};
  23.  
  24. template<template<typename>class Test, typename T, typename=void>
  25. struct base_match2 :std::integral_constant<int, 6> {};
  26. template<template<typename>class Test, typename T>
  27. struct base_match2<Test,T,
  28. typename std::enable_if<0==decltype(helper2<Test>::test(std::declval<T const&>()))::value>::type>
  29. :std::integral_constant<int, 7> {};
  30.  
  31. template<typename T> struct Foo {};
  32.  
  33. template<typename T> struct IsFoo: std::false_type {};
  34. template<typename T> struct IsFoo<Foo<T>>: std::true_type {};
  35.  
  36. typedef Foo<double> Test0;
  37. struct Test1: Foo<int> {};
  38. struct Test2: Foo<int>, Foo<double> {};
  39. struct Test3 {};
  40.  
  41. template<typename T>
  42. using any_base_foo = base_match< Foo, T >;
  43.  
  44. template<typename T>
  45. using any_base2_foo = base_match2< IsFoo, T >;
  46.  
  47. #include <iostream>
  48.  
  49. int main() {
  50. std::cout << "true == " << any_base_foo<Test0>::value << "\n";
  51. std::cout << "true == " << any_base_foo<Test1>::value << "\n";
  52. std::cout << "true == " << any_base_foo<Test2>::value << "\n";
  53. std::cout << "false == " << any_base_foo<Test3>::value << "\n";
  54. std::cout << "false == " << any_base_foo<int>::value << "\n";
  55. std::cout << "method 2\n";
  56. std::cout << "true == " << any_base2_foo<Test0>::value << "\n";
  57. std::cout << "true == " << any_base2_foo<Test1>::value << "\n";
  58. std::cout << "true == " << any_base2_foo<Test2>::value << "\n";
  59. std::cout << "false == " << any_base2_foo<Test3>::value << "\n";
  60. std::cout << "false == " << any_base2_foo<int>::value << "\n";
  61. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
true == 2
true == 2
true == 3
false == 3
false == 3
method 2
true == 6
true == 6
true == 6
false == 6
false == 6