mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-29 16:37:13 +00:00
Merge pull request #226 from dean0x7d/constexpr_arg_check
Check the number of named arguments at compile time
This commit is contained in:
commit
19d95ef09a
@ -321,5 +321,18 @@ template <typename... Args> struct process_attributes {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Compile-time integer sum
|
||||||
|
constexpr size_t constexpr_sum() { return 0; }
|
||||||
|
template <typename T, typename... Ts>
|
||||||
|
constexpr size_t constexpr_sum(T n, Ts... ns) { return n + constexpr_sum(ns...); }
|
||||||
|
|
||||||
|
/// Check the number of named arguments at compile time
|
||||||
|
template <typename... Extra,
|
||||||
|
size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),
|
||||||
|
size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>
|
||||||
|
constexpr bool expected_num_args(size_t nargs) {
|
||||||
|
return named == 0 || (self + named) == nargs;
|
||||||
|
}
|
||||||
|
|
||||||
NAMESPACE_END(detail)
|
NAMESPACE_END(detail)
|
||||||
NAMESPACE_END(pybind11)
|
NAMESPACE_END(pybind11)
|
||||||
|
@ -72,6 +72,9 @@ protected:
|
|||||||
/// Special internal constructor for functors, lambda functions, etc.
|
/// Special internal constructor for functors, lambda functions, etc.
|
||||||
template <typename Func, typename Return, typename... Args, typename... Extra>
|
template <typename Func, typename Return, typename... Args, typename... Extra>
|
||||||
void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) {
|
void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) {
|
||||||
|
static_assert(detail::expected_num_args<Extra...>(sizeof...(Args)),
|
||||||
|
"The number of named arguments does not match the function signature");
|
||||||
|
|
||||||
struct capture { typename std::remove_reference<Func>::type f; };
|
struct capture { typename std::remove_reference<Func>::type f; };
|
||||||
|
|
||||||
/* Store the function including any extra state it might have (e.g. a lambda capture object) */
|
/* Store the function including any extra state it might have (e.g. a lambda capture object) */
|
||||||
@ -206,12 +209,6 @@ protected:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!rec->args.empty() && (int) rec->args.size() != args)
|
|
||||||
pybind11_fail(
|
|
||||||
"cpp_function(): function \"" + std::string(rec->name) + "\" takes " +
|
|
||||||
std::to_string(args) + " arguments, but " + std::to_string(rec->args.size()) +
|
|
||||||
" pybind11::arg entries were specified!");
|
|
||||||
|
|
||||||
rec->signature = strdup(signature.c_str());
|
rec->signature = strdup(signature.c_str());
|
||||||
rec->args.shrink_to_fit();
|
rec->args.shrink_to_fit();
|
||||||
rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__");
|
rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__");
|
||||||
|
Loading…
Reference in New Issue
Block a user