FunctionTraits.h 3.0 KB

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