Use C++17 fold expressions when casting tuples and argument lists

This commit introduces the use of C++17-style fold expressions when
casting tuples & the argument lists of functions.

This change can improve performance of the resulting bindings: because
fold expressions have short-circuiting semantics, pybind11 e.g. won't
try to cast the second argument of a function if the first one failed.
This is particularly effective when working with functions that have
many overloads with long argument lists.
This commit is contained in:
Wenzel Jakob 2019-12-30 00:47:23 +01:00
parent 6e39b765b2
commit fd3a93c520

View File

@ -1432,9 +1432,14 @@ protected:
template <size_t... Is> template <size_t... Is>
bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) { bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
#ifdef __cpp_fold_expressions
if ((... || !std::get<Is>(subcasters).load(seq[Is], convert)))
return false;
#else
for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...}) for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...})
if (!r) if (!r)
return false; return false;
#endif
return true; return true;
} }
@ -1961,9 +1966,14 @@ private:
template <size_t... Is> template <size_t... Is>
bool load_impl_sequence(function_call &call, index_sequence<Is...>) { bool load_impl_sequence(function_call &call, index_sequence<Is...>) {
#ifdef __cpp_fold_expressions
if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])))
return false;
#else
for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...}) for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...})
if (!r) if (!r)
return false; return false;
#endif
return true; return true;
} }