FunctionTraits.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #pragma once
  2. #include <tuple>
  3. // Modified from https://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda
  4. // Fallback, anything with an operator()
  5. template <typename T>
  6. struct function_traits : public function_traits<decltype(&T::operator())> {
  7. };
  8. // Pointers to class members that are themselves functors.
  9. // For example, in the following code:
  10. // template <typename func_t>
  11. // struct S {
  12. // func_t f;
  13. // };
  14. // template <typename func_t>
  15. // S<func_t> make_s(func_t f) {
  16. // return S<func_t> { .f = f };
  17. // }
  18. //
  19. // auto s = make_s([] (int, float) -> double { /* ... */ });
  20. //
  21. // function_traits<decltype(&s::f)> traits;
  22. template <typename ClassType, typename T>
  23. struct function_traits<T ClassType::*> : public function_traits<T> {
  24. };
  25. // Const class member functions
  26. template <typename ClassType, typename ReturnType, typename... Args>
  27. struct function_traits<ReturnType(ClassType::*)(Args...) const> : public function_traits<ReturnType(Args...)> {
  28. };
  29. // Reference types
  30. template <typename T>
  31. struct function_traits<T&> : public function_traits<T> {};
  32. template <typename T>
  33. struct function_traits<T*> : public function_traits<T> {};
  34. // Free functions
  35. template <typename ReturnType, typename... Args>
  36. struct function_traits<ReturnType(Args...)> {
  37. // arity is the number of arguments.
  38. enum { arity = sizeof...(Args) };
  39. typedef std::tuple<Args...> ArgsTuple;
  40. typedef ReturnType result_type;
  41. template <size_t i>
  42. struct arg
  43. {
  44. typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
  45. // the i-th argument is equivalent to the i-th tuple element of a tuple
  46. // composed of those arguments.
  47. };
  48. };
  49. template <typename T>
  50. struct nullary_function_traits {
  51. using traits = function_traits<T>;
  52. using result_type = typename traits::result_type;
  53. };
  54. template <typename T>
  55. struct unary_function_traits {
  56. using traits = function_traits<T>;
  57. using result_type = typename traits::result_type;
  58. using arg1_t = typename traits::template arg<0>::type;
  59. };
  60. template <typename T>
  61. struct binary_function_traits {
  62. using traits = function_traits<T>;
  63. using result_type = typename traits::result_type;
  64. using arg1_t = typename traits::template arg<0>::type;
  65. using arg2_t = typename traits::template arg<1>::type;
  66. };
  67. // Traits for calling with c10::guts::invoke, where member_functions have a first argument of ClassType
  68. template <typename T>
  69. struct invoke_traits : public function_traits<T>{
  70. };
  71. template <typename T>
  72. struct invoke_traits<T&> : public invoke_traits<T>{
  73. };
  74. template <typename T>
  75. struct invoke_traits<T&&> : public invoke_traits<T>{
  76. };
  77. template <typename ClassType, typename ReturnType, typename... Args>
  78. struct invoke_traits<ReturnType(ClassType::*)(Args...)> :
  79. public function_traits<ReturnType(ClassType&, Args...)> {
  80. };
  81. template <typename ClassType, typename ReturnType, typename... Args>
  82. struct invoke_traits<ReturnType(ClassType::*)(Args...) const> :
  83. public function_traits<ReturnType(const ClassType&, Args...)> {
  84. };