fork download
  1. #include <utility>
  2. #include <type_traits>
  3.  
  4.  
  5. template<typename T>
  6. using NoRef = typename std::remove_reference<T>::type;
  7.  
  8. template<typename T>
  9. using EnableIf = typename std::enable_if<T::value, void>::type;
  10.  
  11. template<typename T, typename = void>
  12. struct is_callable_impl : std::is_function<T> {};
  13.  
  14. template<typename T>
  15. struct is_callable_impl<T, EnableIf<std::is_class<NoRef<T>>>> {
  16. using yes = char;
  17. using no = struct { char s[2]; };
  18.  
  19. struct F { void operator()(); };
  20. struct Derived : T, F { };
  21. template<typename U, U> struct Check;
  22.  
  23. template<typename V>
  24. static no test(Check<void (F::*)(), &V::operator()>*);
  25.  
  26. template<typename>
  27. static yes test(...);
  28.  
  29. static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
  30. };
  31.  
  32. template<typename T>
  33. struct Callable : std::integral_constant<bool, is_callable_impl<T>::value> {};
  34.  
  35. struct A {};
  36. struct B {
  37. void operator()();
  38. };
  39.  
  40. struct C {
  41. char operator()(int, int);
  42. };
  43. struct D {
  44. template<typename T, typename U>
  45. void operator()(T, U);
  46. float operator()(int, char, double);
  47. };
  48.  
  49. struct E {
  50. template<typename T>
  51. char operator()(T, double);
  52. };
  53.  
  54. int main() {
  55. static_assert(!Callable<int>::value, "...");
  56. static_assert(Callable<void()>::value, "...");
  57. auto l = [] () { };
  58. static_assert(Callable<decltype(l)>::value, "...");
  59. static_assert(!Callable<A>::value, "...");
  60. static_assert(Callable<B>::value, "...");
  61. static_assert(Callable<C>::value, "...");
  62. static_assert(Callable<D>::value, "...");
  63. static_assert(Callable<E>::value, "...");
  64. }
Success #stdin #stdout 0s 3336KB
stdin
Standard input is empty
stdout
Standard output is empty