mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
Added metatypes for dealing with functions/lambdas
`function_signature_t` extracts the function type from a function, function pointer, or lambda. `is_lambda` (which is really `is_not_a_function_or_pointer_or_member_pointer`, but that name is a bit too long) checks whether the type is (in the approprate context) a lambda. `is_function_pointer` checks whether the type is a pointer to a function.
This commit is contained in:
parent
fd81a03ec9
commit
b4bf5ed575
@ -689,6 +689,31 @@ template <typename T>
|
||||
struct is_input_iterator<T, void_t<decltype(*std::declval<T &>()), decltype(++std::declval<T &>())>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T> using is_function_pointer = bool_constant<
|
||||
std::is_pointer<T>::value && std::is_function<typename std::remove_pointer<T>::type>::value>;
|
||||
|
||||
template <typename F> struct strip_function_object {
|
||||
using type = typename remove_class<decltype(&F::operator())>::type;
|
||||
};
|
||||
|
||||
// Extracts the function signature from a function, function pointer or lambda.
|
||||
template <typename Function, typename F = remove_reference_t<Function>>
|
||||
using function_signature_t = conditional_t<
|
||||
std::is_function<F>::value,
|
||||
F,
|
||||
typename conditional_t<
|
||||
std::is_pointer<F>::value || std::is_member_pointer<F>::value,
|
||||
std::remove_pointer<F>,
|
||||
strip_function_object<F>
|
||||
>::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 <typename T> using is_lambda = satisfies_none_of<remove_reference_t<T>,
|
||||
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 *) { }
|
||||
|
||||
|
@ -1571,10 +1571,10 @@ vectorize(Return (*f) (Args ...)) {
|
||||
}
|
||||
|
||||
// lambda vectorizer:
|
||||
template <typename Func, typename FuncType = typename detail::remove_class<decltype(&detail::remove_reference_t<Func>::operator())>::type>
|
||||
template <typename Func, detail::enable_if_t<detail::is_lambda<Func>::value, int> = 0>
|
||||
auto vectorize(Func &&f) -> decltype(
|
||||
detail::vectorize_extractor(std::forward<Func>(f), (FuncType *) nullptr)) {
|
||||
return detail::vectorize_extractor(std::forward<Func>(f), (FuncType *) nullptr);
|
||||
detail::vectorize_extractor(std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr)) {
|
||||
return detail::vectorize_extractor(std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr);
|
||||
}
|
||||
|
||||
// Vectorize a class method (non-const):
|
||||
|
@ -58,16 +58,11 @@ public:
|
||||
}
|
||||
|
||||
/// Construct a cpp_function from a lambda function (possibly with internal state)
|
||||
template <typename Func, typename... Extra, typename = detail::enable_if_t<
|
||||
detail::satisfies_none_of<
|
||||
detail::remove_reference_t<Func>,
|
||||
std::is_function, std::is_pointer, std::is_member_pointer
|
||||
>::value>
|
||||
>
|
||||
template <typename Func, typename... Extra,
|
||||
typename = detail::enable_if_t<detail::is_lambda<Func>::value>>
|
||||
cpp_function(Func &&f, const Extra&... extra) {
|
||||
using FuncType = typename detail::remove_class<decltype(&detail::remove_reference_t<Func>::operator())>::type;
|
||||
initialize(std::forward<Func>(f),
|
||||
(FuncType *) nullptr, extra...);
|
||||
(detail::function_signature_t<Func> *) nullptr, extra...);
|
||||
}
|
||||
|
||||
/// Construct a cpp_function from a class method (non-const)
|
||||
|
Loading…
Reference in New Issue
Block a user