Advertisement
Guest User

metaprogramming is_callable

a guest
Mar 13th, 2013
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.71 KB | None | 0 0
  1. #include <type_traits>
  2. #include <iostream>
  3.  
  4. template <typename T, bool b = std::is_function<T>::value>
  5. struct is_callable {
  6.     static const bool value = true;
  7. };
  8.  
  9. template <typename T>
  10. struct is_callable <T, false> {
  11.     // Types "yes" and "no" are guaranteed to have different sizes,
  12.     // specifically sizeof(yes) == 1 and sizeof(no) == 2.
  13.     typedef char yes[1];
  14.     typedef char no[2];
  15.  
  16.     struct check_helper {
  17.         operator T();
  18.     };
  19.  
  20.     template <typename TYPE>
  21.     struct helper {
  22.         operator TYPE();
  23.     };
  24.  
  25. //    template <typename C>
  26. //    static yes& test(decltype(C()())*);
  27.  
  28.     template <typename C>
  29.     static yes& test( decltype( static_cast<C>( check_helper() ) () )*);
  30.  
  31.     template <typename>
  32.     static no& test(...);
  33.  
  34.     // If the "sizeof" the result of calling test<T>(0) would be equal to the sizeof(yes),
  35.     // the first overload worked and T has a nested type named foobar.
  36.     static const bool value = sizeof(test<T>(0)) == sizeof(yes);
  37. };
  38.  
  39. template <typename T, typename T2, bool b = std::is_function<T>::value>
  40. struct is_callable_1 {
  41.     static const bool value = true;
  42. };
  43.  
  44. template <typename T, typename T2>
  45. struct is_callable_1<T, T2, false> {
  46.     // Types "yes" and "no" are guaranteed to have different sizes,
  47.     // specifically sizeof(yes) == 1 and sizeof(no) == 2.
  48.     typedef char yes[1];
  49.     typedef char no[2];
  50.  
  51.     struct check_helper {
  52.         operator T();
  53.     };
  54.  
  55.     template <typename TYPE>
  56.     struct helper {
  57.         operator TYPE();
  58.     };
  59.  
  60.     template <typename C>
  61.     static yes& test( decltype( static_cast<C>( check_helper() ) ( helper<T2>() ) )*);
  62.  
  63.     template <typename>
  64.     static no& test(...);
  65.  
  66.     // If the "sizeof" the result of calling test<T>(0) would be equal to the sizeof(yes),
  67.     // the first overload worked and T has a nested type named foobar.
  68.     static const bool value = sizeof(test<T>(0)) == sizeof(yes);
  69. };
  70.  
  71. class Class {
  72.     public:
  73.         void operator() () {}
  74. };
  75.  
  76. class Op {
  77.     public:
  78.         void operator() (int) {}
  79.         void operator() () {}
  80. };
  81.  
  82. void blah (int a = 0) {}
  83.  
  84. int main() {
  85.  
  86.     std::cout << "callable 0" << std::endl;
  87.     std::cout << is_callable<decltype(blah)>::value << std::endl;
  88.     std::cout << is_callable<Class>::value << std::endl;
  89.     std::cout << is_callable<Op>::value << std::endl;
  90.     std::cout << is_callable<int>::value << std::endl;
  91.  
  92.     std::cout << "callable int" << std::endl;
  93.     std::cout << is_callable_1<decltype(blah), int>::value << std::endl;
  94.     std::cout << is_callable_1<Class, int>::value << std::endl;
  95.     std::cout << is_callable_1<Op, int>::value << std::endl;
  96.     std::cout << is_callable_1<int, int>::value << std::endl;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement