Skip to content

Commit 8ef6d79

Browse files
committed
Reduce more template bloat
1 parent f439faa commit 8ef6d79

File tree

3 files changed

+38
-26
lines changed

3 files changed

+38
-26
lines changed

include/pybind11/attr.h

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ enum op_id : int;
117117
enum op_type : int;
118118
struct undefined_t;
119119
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t> struct op_;
120-
template <size_t NumArgs> void keep_alive_impl(size_t Nurse, size_t Patient, function_call_impl<NumArgs> &call, handle ret);
120+
void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
121121
template <typename... Args> struct process_attributes;
122122

123123
template <typename T>
@@ -966,8 +966,8 @@ template <typename T> struct process_attribute_default {
966966
/// Default implementation: do nothing
967967
static void init(const T &, function_record *) { }
968968
static void init(const T &, type_record *) { }
969-
template<size_t NumArgs> static void precall(function_call_impl<NumArgs> &) { }
970-
template<size_t NumArgs> static void postcall(function_call_impl<NumArgs> &, handle) { }
969+
static void precall(function_call &) { }
970+
static void postcall(function_call &, handle) { }
971971
};
972972

973973
/// Process an attribute specifying the function's name
@@ -1107,14 +1107,14 @@ struct process_attribute<call_guard<Ts...>> : process_attribute_default<call_gua
11071107
* otherwise
11081108
*/
11091109
template <size_t Nurse, size_t Patient> struct process_attribute<keep_alive<Nurse, Patient>> : public process_attribute_default<keep_alive<Nurse, Patient>> {
1110-
template <size_t NumArgs, size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
1111-
static void precall(function_call_impl<NumArgs> &call) { keep_alive_impl(Nurse, Patient, call, handle()); }
1112-
template <size_t NumArgs, size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
1113-
static void postcall(function_call_impl<NumArgs> &, handle) { }
1114-
template <size_t NumArgs, size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
1115-
static void precall(function_call_impl<NumArgs> &) { }
1116-
template <size_t NumArgs, size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
1117-
static void postcall(function_call_impl<NumArgs> &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); }
1110+
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
1111+
static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); }
1112+
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
1113+
static void postcall(function_call &, handle) { }
1114+
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
1115+
static void precall(function_call &) { }
1116+
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
1117+
static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); }
11181118
};
11191119

11201120
/// Recursively iterate over variadic template arguments
@@ -1127,13 +1127,11 @@ template <typename... Args> struct process_attributes {
11271127
int unused[] = { 0, (process_attribute<typename std::decay<Args>::type>::init(args, r), 0) ... };
11281128
ignore_unused(unused);
11291129
}
1130-
template<size_t NumArgs>
1131-
static void precall(function_call_impl<NumArgs> &call) {
1130+
static void precall(function_call &call) {
11321131
int unused[] = { 0, (process_attribute<typename std::decay<Args>::type>::precall(call), 0) ... };
11331132
ignore_unused(unused);
11341133
}
1135-
template<size_t NumArgs>
1136-
static void postcall(function_call_impl<NumArgs> &call, handle fn_ret) {
1134+
static void postcall(function_call &call, handle fn_ret) {
11371135
int unused[] = { 0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0) ... };
11381136
ignore_unused(unused);
11391137
}

include/pybind11/cast.h

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,10 +1884,12 @@ NAMESPACE_BEGIN(detail)
18841884

18851885
struct function_call
18861886
{
1887-
function_call(handle p) : parent(p) {}
1887+
function_call(handle p, size_t n) : parent(p), num_args(n) {}
18881888

18891889
virtual ~function_call() {}
18901890
virtual void set_arg(size_t idx, handle h, bool convert) = 0;
1891+
virtual handle arg_at(size_t idx) const = 0;
1892+
virtual bool arg_convert_at(size_t idx) const = 0;
18911893

18921894
public:
18931895
/// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if
@@ -1899,19 +1901,32 @@ struct function_call
18991901

19001902
/// If this is a call to an initializer, this argument contains `self`
19011903
handle init_self;
1904+
1905+
/// Number of arguments
1906+
size_t num_args;
19021907
};
19031908

19041909
/// Internal data associated with a single function call
19051910
template<size_t NumArgs>
19061911
struct function_call_impl : function_call {
1907-
using function_call::function_call;
1912+
function_call_impl(handle p) : function_call(p, NumArgs) {}
19081913

1909-
PYBIND11_NOINLINE void set_arg(size_t idx, handle h, bool convert) override
1914+
void set_arg(size_t idx, handle h, bool convert) override
19101915
{
19111916
args[idx] = h;
19121917
args_convert.set(idx, convert);
19131918
}
19141919

1920+
handle arg_at(size_t idx) const override
1921+
{
1922+
return args[idx];
1923+
}
1924+
1925+
bool arg_convert_at(size_t idx) const override
1926+
{
1927+
return args_convert[idx];
1928+
}
1929+
19151930
public:
19161931
/// Arguments passed to the function:
19171932
std::array<handle, NumArgs> args;
@@ -1943,7 +1958,7 @@ class argument_loader {
19431958

19441959
static constexpr auto arg_names = concat(type_descr(make_caster<Args>::name)...);
19451960

1946-
bool load_args(function_call_impl<num_args> &call) {
1961+
bool load_args(function_call &call) {
19471962
return load_impl_sequence(call, indices{});
19481963
}
19491964

@@ -1960,11 +1975,11 @@ class argument_loader {
19601975

19611976
private:
19621977

1963-
static bool load_impl_sequence(function_call_impl<num_args>&, index_sequence<>) { return true; }
1978+
static bool load_impl_sequence(function_call&, index_sequence<>) { return true; }
19641979

19651980
template <size_t... Is>
1966-
bool load_impl_sequence(function_call_impl<num_args>&call, index_sequence<Is...>) {
1967-
for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...})
1981+
bool load_impl_sequence(function_call &call, index_sequence<Is...>) {
1982+
for (bool r : {std::get<Is>(argcasters).load(call.arg_at(Is), call.arg_convert_at(Is))...})
19681983
if (!r)
19691984
return false;
19701985
return true;

include/pybind11/pybind11.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -966,15 +966,14 @@ inline void keep_alive_impl(handle nurse, handle patient) {
966966
}
967967
}
968968

969-
template<size_t NumArgs>
970-
PYBIND11_NOINLINE void keep_alive_impl(size_t Nurse, size_t Patient, function_call_impl<NumArgs> &call, handle ret) {
969+
PYBIND11_NOINLINE inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) {
971970
auto get_arg = [&](size_t n) {
972971
if (n == 0)
973972
return ret;
974973
else if (n == 1 && call.init_self)
975974
return call.init_self;
976-
else if (n <= call.args.size())
977-
return call.args[n - 1];
975+
else if (n <= call.num_args)
976+
return call.arg_at(n - 1);
978977
return handle();
979978
};
980979

0 commit comments

Comments
 (0)