diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index c7b69f58b..7397e2be9 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -689,6 +689,31 @@ template struct is_input_iterator()), decltype(++std::declval())>> : std::true_type {}; +template using is_function_pointer = bool_constant< + std::is_pointer::value && std::is_function::type>::value>; + +template struct strip_function_object { + using type = typename remove_class::type; +}; + +// Extracts the function signature from a function, function pointer or lambda. +template > +using function_signature_t = conditional_t< + std::is_function::value, + F, + typename conditional_t< + std::is_pointer::value || std::is_member_pointer::value, + std::remove_pointer, + strip_function_object + >::type +>; + +/// Returns true if the type looks like a lambda: that is, isn't a function, pointer or member +/// pointer. Note that this can catch all sorts of other things, too; this is intended to be used +/// in a place where passing a lambda makes sense. +template using is_lambda = satisfies_none_of, + std::is_function, std::is_pointer, std::is_member_pointer>; + /// Ignore that a variable is unused in compiler warnings inline void ignore_unused(const int *) { } diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 4ee256192..4bea46029 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -1571,10 +1571,10 @@ vectorize(Return (*f) (Args ...)) { } // lambda vectorizer: -template ::operator())>::type> +template ::value, int> = 0> auto vectorize(Func &&f) -> decltype( - detail::vectorize_extractor(std::forward(f), (FuncType *) nullptr)) { - return detail::vectorize_extractor(std::forward(f), (FuncType *) nullptr); + detail::vectorize_extractor(std::forward(f), (detail::function_signature_t *) nullptr)) { + return detail::vectorize_extractor(std::forward(f), (detail::function_signature_t *) nullptr); } // Vectorize a class method (non-const): diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 9bf39d145..bd0ee2733 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -58,16 +58,11 @@ public: } /// Construct a cpp_function from a lambda function (possibly with internal state) - template , - std::is_function, std::is_pointer, std::is_member_pointer - >::value> - > + template ::value>> cpp_function(Func &&f, const Extra&... extra) { - using FuncType = typename detail::remove_class::operator())>::type; initialize(std::forward(f), - (FuncType *) nullptr, extra...); + (detail::function_signature_t *) nullptr, extra...); } /// Construct a cpp_function from a class method (non-const)