mirror of
https://github.com/RYDE-WORK/pybind11.git
synced 2026-02-02 21:45:53 +08: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 &>())>>
|
struct is_input_iterator<T, void_t<decltype(*std::declval<T &>()), decltype(++std::declval<T &>())>>
|
||||||
: std::true_type {};
|
: 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
|
/// Ignore that a variable is unused in compiler warnings
|
||||||
inline void ignore_unused(const int *) { }
|
inline void ignore_unused(const int *) { }
|
||||||
|
|
||||||
|
|||||||
@ -1571,10 +1571,10 @@ vectorize(Return (*f) (Args ...)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lambda vectorizer:
|
// 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(
|
auto vectorize(Func &&f) -> decltype(
|
||||||
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), (FuncType *) nullptr);
|
return detail::vectorize_extractor(std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vectorize a class method (non-const):
|
// Vectorize a class method (non-const):
|
||||||
|
|||||||
@ -58,16 +58,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a cpp_function from a lambda function (possibly with internal state)
|
/// Construct a cpp_function from a lambda function (possibly with internal state)
|
||||||
template <typename Func, typename... Extra, typename = detail::enable_if_t<
|
template <typename Func, typename... Extra,
|
||||||
detail::satisfies_none_of<
|
typename = detail::enable_if_t<detail::is_lambda<Func>::value>>
|
||||||
detail::remove_reference_t<Func>,
|
|
||||||
std::is_function, std::is_pointer, std::is_member_pointer
|
|
||||||
>::value>
|
|
||||||
>
|
|
||||||
cpp_function(Func &&f, const Extra&... extra) {
|
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),
|
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)
|
/// Construct a cpp_function from a class method (non-const)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user