#ifndef FUNCTIONTRAITS_H #define FUNCTIONTRAITS_H #include #include #include template class FunctionTraits; template struct IsTuple : std::false_type { enum { num = 1, }; }; template struct IsTuple> : std::true_type { enum { num = std::tuple_size>::value, }; }; template struct IsTuple> : std::true_type { enum { num = std::tuple_size>::value, }; }; template class FunctionTraits { public: enum { arity = sizeof...(Args), Results = IsTuple::num }; using FunctionType = Ret(Args...); using FunctionPointerType = FunctionType *; using ReturnType = Ret; using StlFunctionType = std::function; using Arguments = std::tuple; template class Argument { public: static_assert(I < arity, "index is out of range, index must less than sizeof Args..."); using Type = std::tuple_element_t; }; using FirstArgumentType = typename Argument<0>::Type; }; template class FunctionTraits { public: enum { arity = 0, Results = IsTuple::num }; using FunctionType = Ret(); using FunctionPointerType = FunctionType *; using ReturnType = Ret; using StlFunctionType = std::function; using Arguments = std::tuple<>; using FirstArgumentType = void; template class Argument { public: using Type = void; }; }; template <> class FunctionTraits { public: using Arguments = std::tuple<>; using FirstArgumentType = void; template class Argument { public: using Type = void; }; }; template class FunctionTraits : public FunctionTraits {}; template class FunctionTraits> : public FunctionTraits {}; template class FunctionTraits : public FunctionTraits {}; template class FunctionTraits : public FunctionTraits {}; template class FunctionTraits : public FunctionTraits {}; template class FunctionTraits : public FunctionTraits {}; // std::bind for object methods rclcpp/rclcpp/include/rclcpp/function_traits.hpp template #if defined _GLIBCXX_RELEASE // glibc++ (GNU C++ >= 7.1) struct FunctionTraits> #elif defined __GLIBCXX__ // glibc++ (GNU C++) struct FunctionTraits(FArgs...)>> #elif defined _MSC_VER // MS Visual Studio struct FunctionTraits> #elif defined __clang__ struct FunctionTraits> #else #error "Unsupported C++ compiler / standard library" #endif : FunctionTraits { }; // template // class FunctionTraits> // : public FunctionTraits::operator())> {}; template class FunctionTraits : public FunctionTraits {}; template typename FunctionTraits>::StlFunctionType makeStlFunction(Function &&lambda) { return static_cast>::StlFunctionType>(std::forward(lambda)); } /*! * \struct HasCallOperator * http://stackoverflow.com/a/5117641 */ template struct HasCallOperator { template static char check(decltype(&U::operator(), char(0))); template static char (&check(...))[2]; static const bool value = (sizeof(check(0)) == 1); }; /*! * \struct ArgsOf * http://stackoverflow.com/a/7943765 * http://stackoverflow.com/a/27885283 */ template struct ArgsTraits { using types = std::tuple; using first = typename std::tuple_element<0, types>::type; static const size_t count = std::tuple_size::value; }; template <> struct ArgsTraits<> { using types = std::tuple<>; using first = void; static const size_t count = 0; }; // Fallback implementation, including types (T) which are not functions but // also lambda with `auto` arguments, which are not covered but still valid // callbacks (see the QPromiseBase template constructor). template struct ArgsOf : public ArgsTraits<> {}; // Partial specialization for null function. template <> struct ArgsOf : public ArgsTraits<> {}; // Partial specialization for type with a non-overloaded operator(). // This applies to lambda, std::function but not to std::bind result. template struct ArgsOf::value>::type> : public ArgsOf {}; // Partial specialization to remove reference and rvalue (e.g. lambda, std::function, etc.). template struct ArgsOf : public ArgsOf {}; template struct ArgsOf : public ArgsOf {}; // Partial specialization for function type. template struct ArgsOf : public ArgsTraits {}; // Partial specialization for function pointer. template struct ArgsOf : public ArgsTraits {}; // Partial specialization for pointer-to-member-function (i.e. operator()'s). template struct ArgsOf : public ArgsTraits {}; template struct ArgsOf : public ArgsTraits {}; template struct ArgsOf : public ArgsTraits {}; template struct ArgsOf : public ArgsTraits {}; #endif // FUNCTIONTRAITS_H